GitHub: リポジトリコラボレーター削除

GitHub: リポジトリコラボレーター削除

GitHub: Remove Repository Collaborator

この工程は、GitHub の指定したリポジトリのコラボレーターを削除します。

Basic Configs
工程名
メモ
Auto Step icon
Configs for this Auto Step
conf_Auth
C1: 個人用アクセストークン(fine-grained) *
conf_RepositoryUrl
C2: リポジトリの URL (https://github.com/{owner}/{repository}) *
conf_UserName
C3: GitHub コラボレータのハンドル名 *

Notes

  • 個人用アクセストークン(fine-grained)の作成方法については、GitHub のドキュメントを参照してください
    • リポジトリコラボレータの削除には、Repository permissions > Administration > Read and Write のアクセス許可が必要です

Capture

See Also

Script (click to open)

  • 次のスクリプトが記述されている XML ファイルをダウンロードできます

    • github-repository-collaborater-remove.xml (C) Questetra, Inc. (MIT License)
    • Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます


const API_VERSION = '2022-11-28';
const API_VERSION_HEADER = 'X-GitHub-Api-Version';
const main = () => {
    ////// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
    const auth = configs.getObject('conf_Auth');
    const ownerAndRepo = retrieveOwnerAndRepo();
    const handle = retrieveHandle();
    ////// == 演算 / Calculating ==
    const invitationId = checkInvitee(auth, ownerAndRepo, handle);
    if (invitationId !== undefined){
        // 招待中のユーザは、コラボレータ削除 API では削除できないため、招待削除 API で削除する
        const isInvitationRemoved = removeInvitation(auth, ownerAndRepo, handle, invitationId);
        if (isInvitationRemoved) {
            return;
        }
    }
    // コラボレータでない、招待していない、GitHub ユーザでない 場合に、エラーにしたい
    // しかし、コラボレータ削除の API は、これらも削除成功と同様 204 レスポンスを返し、区別できない
    // だから事前にコラボレータであるかどうかチェックする
    checkCollaborator(auth, ownerAndRepo, handle);
    removeCollaborator(auth, ownerAndRepo, handle);
}
/**
  * config からリポジトリの URL を読み出し、API に必要な文字列を取り出す
  * @return {String} ownerAndRepo
  */
const retrieveOwnerAndRepo = () => {
    const repositoryUrlDef = configs.getObject('conf_RepositoryUrl');
    let repositoryUrl;
    if (repositoryUrlDef === null) { // 固定値で指定
        repositoryUrl = configs.get('conf_RepositoryUrl');
    } else {
        repositoryUrl = engine.findData(repositoryUrlDef);
    }
    if (repositoryUrl === null) {
        throw new Error("Repository's URL is blank.");
    }
    const regExp = /^https:\/\/github\.com\/([a-zA-Z0-9-_]+\/[a-zA-Z0-9-_]+)$/;
    const found = repositoryUrl.match(regExp);
    if (found === null) {
        throw new Error("Invalid repository URL.");
    }
    const ownerAndRepo = found[1];
    return ownerAndRepo;
}
/**
  * config から削除する GitHub ユーザのハンドル名 を読み出す
  * @return {String} handle
  */
const retrieveHandle = () => {
    const handleDef = configs.getObject('conf_UserName');
    let handle;
    if (handleDef === null) { // 固定値で指定
        handle = configs.get('conf_UserName');
    } else {
        handle = engine.findData(handleDef);
    }
    if (handle === null) {
        throw new Error("handle is blank.");
    }
    return handle;
}
/**
  * ユーザーがリポジトリ招待中であるかどうかを確認する
  * @param {AuthSettingWrapper} auth HTTP 認証設定
  * @param {String} ownerAndRepo {owner}/{repo}
  * @param {String} handle 削除する GitHub ユーザのハンドル名
  * @return {String} invitationsId 招待 ID
  */
const checkInvitee = (auth, ownerAndRepo, handle) => {
    const url = `https://api.github.com/repos/${ownerAndRepo}/invitations`;
    const MAX_PER_PAGE = 100;
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .queryParam("per_page", MAX_PER_PAGE.toString())
        .get(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 200) {
        engine.log(responseStr);
        throw new Error(`Failed to get invitee information. status: ${status}`);
    }
    const invitations = JSON.parse(responseStr);
    if (invitations.length === MAX_PER_PAGE) {
       throw new Error("Too many invitations found.");
    }
    const invitation = invitations.find((element) => element.invitee.login === handle);
    if (invitation === undefined){
        return undefined;
    }
    engine.log('Invitation found.');
    return invitation.id;
};
/**
 * リポジトリ招待中のユーザについて招待を削除(キャンセル)する
 * 招待中のユーザは、コラボレータ削除 API では削除できないため、招待削除 API で削除する
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} ownerAndRepo {owner}/{repo}
 * @param {String} handle 削除する GitHub ユーザのハンドル名
 * @param {String} invitationId  GitHub ユーザの招待 ID
 */
const removeInvitation = (auth, ownerAndRepo, handle, invitationId) => {
    const url = `https://api.github.com/repos/${ownerAndRepo}/invitations/${invitationId}`;
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .delete(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status === 204) { // 招待のキャンセル成功
        engine.log(`Succeeded to remove the invitation(${handle}).`);
        return true;
    }
    if (status === 404) { // 招待が承認済み or キャンセル済み
        engine.log(`Failed to remove invitation as it is already approved or removed.`);
        return false;
    }
    engine.log(responseStr);
    throw new Error(`Failed to remove the invitation. status: ${status}`);
};
/**
 * ユーザーがリポジトリコラボレータであるかどうかを確認する
 * コラボレータでない、招待していない、GitHub ユーザでない 場合に、エラーにしたい
 * しかし、コラボレータ削除の API は、これらも削除成功と同様 204 レスポンスを返し、区別できない
 * だから事前にコラボレータであるかどうかチェックする
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} ownerAndRepo {owner}/{repo}
 * @param {String} handle 削除する GitHub ユーザのハンドル名
 */
const checkCollaborator = (auth, ownerAndRepo, handle) => {
    const url = `https://api.github.com/repos/${ownerAndRepo}/collaborators/${encodeURIComponent(handle)}`;
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .get(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status === 204) {
        // success: the user is a collaborator
        return;
    }
    if (status === 404) {
        throw new Error(`${handle} is not a collaborator. status: ${status}`);
    }
    engine.log(responseStr);
    throw new Error(`Failed to get a ${handle} information. status: ${status}`);
};
/**
 * リポジトリのコラボレータを削除
 * @param {AuthSettingWrapper} auth HTTP 認証設定
 * @param {String} ownerAndRepo {owner}/{repo}
 * @param {String} handle 削除する GitHub ユーザのハンドル名
 */
const removeCollaborator = (auth, ownerAndRepo, handle) => {
    const url = `https://api.github.com/repos/${ownerAndRepo}/collaborators/${encodeURIComponent(handle)}`;
    const response = httpClient.begin()
        .header(API_VERSION_HEADER, API_VERSION)
        .authSetting(auth)
        .delete(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 204) {
        engine.log(responseStr);
        throw new Error(`Failed to remove a collaborator. status: ${status}`);
    }
    engine.log(`Succeeded to remove a collaborator(${handle}).`);
};

上部へスクロール

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む