概要
本記事はGitHub ActionsとGitHub APIを使って、一般から閲覧できない組織(Organization)のPrivateメンバーを動的に取得します。
認証はGitHub Appsを用いて設定します。
GitHub APIの取得制限を回避するためのループ処理でPythonを使用します。
やりたいこと
GitHub上のユーザーをプログラムで取得して処理を定義したい場合、専用のREST APIが用意されています。
PublicなメンバーであればAPIをそのまま叩くだけで取得できるのですが、Privateなメンバーは認証等を設定する必要があります。
本記事ではOrganizationに所属するユーザーを対象にして、Public+Privateなメンバーを取得する基盤を構築します。
全体像
GitHub REST APIのList organization membersを使用します。
Organizationメンバー - GitHub Enterprise Server 3.2 Docs
単にAPIを叩くだけでは以下のようにプライベート設定のメンバーを取得できません。
今回はGitHub Appsを設定して認証を行わせることで、Publicでないメンバー情報を取得する設定を行います。
手順
GitHub Appsの作成
Organizationのメンバーを取得するために認証が必要になります。
権限を持ったユーザーのPersonal Access tokenか、GitHub Appsが選択肢に入るかと思います。
いずれでも取得は可能ですが今回はOrgsが対象のため、組織共通の認証基盤として使用できるGitHub Appsを用います。
対象のOrganizationのSettingsを開きます
左のメニューからDevelopper settings -> GitHub Appsを開きます
New GitHub Appを選択します
設定画面で次の項目を入力します
- GitHub App Name
- GitHubアプリの名称を決定
- Webhook/Active
- 不要のためチェックを外す
- Permissions
- 以下の3点のみ設定
- Repository Permissions
- Metadata
- Read-Onlyに設定
- Secrets
- Read-Onlyに設定
- Metadata
- Organization Permissions
- Members
- Read-Onlyに設定
- Members
- Repository Permissions
- 以下の3点のみ設定
- GitHub App Name
GitHub Apps設定画面のInstall Appを開いて、表示されているOrganizationにGitHub Appをインストールします(画像はインストール後のもの)
GitHub Apps設定画面のGeneralを開いて、最上段の項目から「App Id」を控えておきます
Private Keyの項目から「Generate a private key」を選択します Private Keyの.pemファイルがローカル環境にダウンロードされるため、中身を確認します
GitHub Actionsのワークフローを実行するリポジトリのSettingsを開きます
一覧からSecrets-Actionsを選択して、「New repository secret」から以下の2つを作成します- APP_ID
- 手順6で控えたApp Id
- PRIVATE_KEY
- 手順7でローカル環境に落としたPrivateKeyの全文
- APP_ID
GitHub Actionsの作成
基本のワークフロー
GitHub Actionsを設定するためのリポジトリに、以下のworkflowファイルを作成します。
.github/workflows/main.yaml
name: orgs prvate member list on: workflow_dispatch: jobs: terraform: name: test runs-on: ubuntu-latest defaults: run: shell: bash steps: - name: Checkout uses: actions/checkout@v2 - name: Generate github token id: generate_token uses: tibdex/github-app-token@v1 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.PRIVATE_KEY }} - name: org member list run: | gh api /orgs/[対象Organization名]/members?per_page=100 env: GH_TOKEN: ${{ steps.generate_token.outputs.token }}
gh apiコマンドでGitHub REST APIを呼び出します。
?per_page=100
とすることで、上限である100人までのメンバーを取得します。これを設定しない場合は30人までしか取得できないため注意してください。
101~200人目のメンバーはpage=2
と指定することで取得できます。
この実装にはループ処理が必要であったため、筆者はActions以外にPythonスクリプトを書いて実装しました。
ループ処理の実装(Python)
101人目以降のメンバーを取得するために以下のように処理を定義します。
main.py
import requests import json args = sys.argv GITHUB_TOKEN = args[1] GITHUB_REPOSITORY = args[2] ORG_NAME = GITHUB_REPOSITORY.split('/')[0] # ヘッダー header_github = { 'Accept':'application/vnd.github+json', 'Authorization': 'token '+GITHUB_TOKEN } def get_request_url(url,header): ''' GETリクエストを送信してJSONを受け取るメソッド ''' r = requests.get(url, headers=header) if r.status_code != 200: print('API call failed.', flush=True) print(r.text, flush=True) data = r.json() return data # github userget members_req_url = f'https://api.github.com/orgs/{ORG_NAME}/members?per_page=100' data_users = [] for i in range(1,1000): data_users_temp = get_request_url(members_req_url+"&page="+str(i), header_github) if len(data_users_temp)==0: break data_users += data_users_temp print("data_mamber_users:", len(data_users), flush=True)
data_usersリストに名前が格納されるので、これを使ってその他処理を定義していくことができます。
GitHub ActionsでPythonを実行する際、ログにprint文で記載した内容を表示させることができます。
重い処理をさせた際に実行順序が入れ替わったりすることがあるため、オプションでflush=Trueを挿入することを推奨します。
.github/workflows/main.yml (抜粋)
- name: Setup Python uses: actions/setup-python@v2 with: python-version: '3.8' architecture: 'x64' - name: Install dependencies run: pip install -r requirements.txt - name: Run Python run: python main.py ${{ steps.generate_token.outputs.token }} ${{ github.repository }} - name: Print End date run: | echo $(TZ=Asia/Tokyo date '+%Y-%m-%d %H:%M:%S(%z)')
基本ワークフローのorg member list項と上記を置き換えて定義します。
Privateメンバーを取得するためのトークンをGenerate github tokenから取得し、リポジトリ名(Organization名)はデフォルト定義の変数から取得して引数としてPythonに与えます。
requirements.txt
requests==2.24.0
一部pipインストールが必要なパッケージをrequirements.txtで定義して、仮想マシン環境にインストールします。
実行結果(基本のワークフロー)
Workflowの実行は手動で行います。
実行結果
Privateに設定した自身のユーザー情報が取得できました。
Publicなメンバーが在籍している場合についても、認証不要のため同様に取得されます。
その他
外部コラボレーターを取得したい場合は、以下のAPIを叩けば同様に取得できます。
List outside collaborators for an organization
その他Orginizationに関するPrivateな情報を取得するAPIを叩く場合も、同様の方法でリクエストを送ればよいので、色々試してみてください。
おわりに
今回はGitHub Appsを使って認証が必要なPrivateなOrganizationメンバーを取得しました。
同様の方法でトークンを発行してPrivate情報を取得することができるので、応用して色々なAPIを試してみてください。