GitHub: Create Repository

GitHub: Create Repository

GitHub: リポジトリ作成

This item creates a repository on GitHub.

Basic Configs
Step Name
Note
Auto Step icon
Configs for this Auto Step
conf_Auth
C1: Personal Access Token (fine-grained) *
conf_Org
C2: Organization Name (if blank, create the user’s repository)
conf_Name
C3: Repository Name *#{EL}
conf_Visibility
C4: Visibility *
conf_License
C5: License
conf_GitIgnore
C6: .gitignore Template (input the name without the extension)
conf_Description
C7: Description#{EL}
conf_Homepage
C8: Website#{EL}
conf_Topics
C9: Topics (write one per line)
conf_Url
C10: Data item to save the repository’s URL

Notes

  • To learn about how to create your Personal Access Token (fine-grained), see the GitHub documentation
    • To create a repository, the token requires the following permission: Repository permissions > Administration > Read and Write
  • [C5: License] can be set to a fixed value, even if the license is not one of the options
  • To set up [C6: .gitignore Template], choose one .gitignore file from the gitignore repository and input the character string before .gitignore
    • Ex. If you would like to use Node.gitignore, input Node

Capture

See Also

Script (click to open)
  • An XML file that contains the code below is available to download
    • github-repository-create.xml (C) Questetra, Inc. (MIT License)
    • If you are using Professional, you can modify the contents of this file and use it as your own add-on auto step


const API_VERSION = '2022-11-28';
const API_VERSION_HEADER = 'X-GitHub-Api-Version';

const MAX_TOPIC_NUM = 20;
const MAX_TOPIC_LENGTH = 50;

function main() {
    ////// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
    const auth = configs.getObject('conf_Auth');
    const org = configs.get('conf_Org');
    const name = configs.get('conf_Name');
    if (name === '') {
        throw new Error('Repository Name is blank.');
    }
    const visibility = configs.get('conf_Visibility');
    const license = configs.get('conf_License');
    const gitIgnore = configs.get('conf_GitIgnore');
    const description = configs.get('conf_Description');
    const homepage = configs.get('conf_Homepage');
    const topics = retrieveTopics();

    ////// == 演算 / Calculating ==
    let repo;
    if (org === '') {
        repo = createRepositoryForUser(auth, name, visibility, license, gitIgnore, description, homepage);
    } else {
        repo = createRepositoryForOrganization(auth, org, name, visibility, license, gitIgnore, description, homepage);
    }
    if (topics.length > 0) {
        setTopics(auth, repo.full_name, topics);
    }

    ////// == ワークフローデータへの代入 / Data Updating ==
    saveData('conf_Url', repo.html_url);
}

/**
 * config に設定されたトピックを読み出す
 * @returns {Array<String>} トピックの配列
 */
const retrieveTopics = () => {
    const dataDef = configs.getObject('conf_Topics');
    if (dataDef === null) {
        return [];
    }
    let topics = [];
    if (dataDef.matchDataType('STRING')) { // 文字型データ項目の場合
        const dataObj = engine.findData(dataDef);
        if (dataObj === null) {
            return [];
        }
        topics = dataObj.split('\n')
            .filter(name => name !== '');
    } else { // 選択型データ項目の場合
        const selects = engine.findData(dataDef);
        if (selects === null || selects.size() === 0) {
            return [];
        }
        selects.forEach(item => {
            topics.push(item.getValue());
        });
    }
    // バリデーション
    if (topics.length > MAX_TOPIC_NUM) {
        throw new Error(`The maximum number of topics is ${MAX_TOPIC_NUM}.`);
    }
    if (topics.some(topic => topic.length > MAX_TOPIC_LENGTH)) {
        throw new Error(`Each topic must be within ${MAX_TOPIC_LENGTH} characters.`);
    }
    const reg = new RegExp(`^[a-z0-9-]+$`);
    if (!topics.every(topic => reg.test(topic))) {
        throw new Error('Topics can only include lowercase letters, numbers, and hyphens.');
    }
    return topics;
};

/**
 * ユーザのリポジトリを作成
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} name リポジトリ名
 * @param {String} visibility 公開設定
 * @param {String} license ライセンス
 * @param {String} gitIgnore .gitignore テンプレート
 * @param {String} description 説明
 * @param {String} homepage ウェブサイト
 * @returns {Object} レポジトリ情報
 */
const createRepositoryForUser = (auth, name, visibility, license, gitIgnore, description, homepage) => {
    const url = 'https://api.github.com/user/repos';

    const private = visibility === 'private';
    const payload = {name, private, description, homepage};
    if (license !== '') {
        payload.license_template = license;
    }
    if (gitIgnore !== '') {
        payload.gitignore_template = gitIgnore;
    }
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .body(JSON.stringify(payload), 'application/json')
        .post(url);

    const status = response.getStatusCode();
    const respTxt = response.getResponseAsString();
    if (status !== 201) {
        engine.log(respTxt);
        throw new Error(`Failed to create a repository for the user. status: ${status}`);
    }
    return JSON.parse(respTxt);
};

/**
 * 組織のリポジトリを作成
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} org 組織名
 * @param {String} name リポジトリ名
 * @param {String} visibility 公開設定
 * @param {String} license ライセンス
 * @param {String} gitIgnore .gitignore テンプレート
 * @param {String} description 説明
 * @param {String} homepage ウェブサイト
 * @returns {Object} レポジトリ情報
 */
const createRepositoryForOrganization = (auth, org, name, visibility, license, gitIgnore, description, homepage) => {
    const url = `https://api.github.com/orgs/${encodeURIComponent(org)}/repos`;

    const payload = {name, visibility, description, homepage};
    if (license !== '') {
        payload.license_template = license;
    }
    if (gitIgnore !== '') {
        payload.gitignore_template = gitIgnore;
    }
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .body(JSON.stringify(payload), 'application/json')
        .post(url);

    const status = response.getStatusCode();
    const respTxt = response.getResponseAsString();
    if (status !== 201) {
        engine.log(respTxt);
        throw new Error(`Failed to create a repository for the organization. status: ${status}`);
    }
    return JSON.parse(respTxt);
};

/**
 * リポジトリのトピックを設定
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} fullName リポジトリのパス
 * @param {Array<String>} topics トピック
 */
const setTopics = (auth, fullName, topics) => {
    const url = `https://api.github.com/repos/${fullName}/topics`;

    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .body(JSON.stringify({names: topics}), 'application/json')
        .put(url);

    const status = response.getStatusCode();
    const respTxt = response.getResponseAsString();
    if (status !== 200) {
        engine.log(respTxt);
        throw new Error(`Failed to set topics. status: ${status}`);
    }
};

/**
 * データ項目への保存
 * @param {String} configName 設定名
 * @param {Object} data 保存するデータ
 */
const saveData = (configName, data) => {
    const def = configs.getObject(configName);
    if (def === null) {
        return;
    }
    engine.setData(def, data);
};

Scroll to Top

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading