GitHub App で取得した Token を利用し、 GitHub スクリプトでスマートに GitHub Organization にアクセスする

GitHub Actions で GitHub に対する操作を自動化する際に、GitHub App によって生成するトークンを使用することができます。

また、[GitHub スクリプト](https://github.com/actions/github-script)を使用すれば GitHub に対する操作の記述がスマートに行えます。

GitHub Organization の Variable を取得する処理を例に、対応や実装例を記載します。

## GitHub App の作成

必須入力の関連の設定値は下記です。

| 設定項目                                | 値                                                          |
| --------------------------------------- | ----------------------------------------------------------- |
| GitHub App name                         | 任意の名前。今回は `list-variables` を想定                  |
| Homepage URL                            | 任意の URL                                                  |
| Webhook                                 | Active を外す                                               |
| Permissions                             | Organization permissions で Variables の `read-only` を設定 |
| Where can this GitHub App be installed? | `Any account`                                               |

作成後に表示される画面の `App ID:` のところに GitHub App の ID が記載されるのでメモしておきます。

## GitHub App の Private key の作成

GitHub App 作成後の画面を下にスクロールすると、`Private keys` という欄があります。

もし閉じてしまったら、https://github.com/settings/apps から作成した GitHub App の Edit ボタンで戻ってこれます。

`Generate a private key` のボタンを押すことで Private key の生成とダウンロードを行います。

## GitHub App を Organization に Install する

作成した GitHub App が Organization の情報を取得できるよう、Organization に Install します。

Private key の作成時に開いていた画面の左側に「Install App」という項目があるのでクリックし、Install 先の Organization に対してインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/c7bc4b52-c097-ead3-d5a5-f6c117f9af5c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/a54c7adf-3c59-8976-da41-db24f2fe6a38.png)

Organization の管理者でない場合、[設定によっては管理者に承認される必要があります](https://docs.github.com/ja/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization#fine-grained-personal-access-token-%E3%81%AE%E6%89%BF%E8%AA%8D%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%82%92%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B)。

## workflow 作成用のリポジトリで Secret を設定

workflow 作成用の GitHub リポジトリを用意し、workflow から GitHub App の接続情報にアクセスできるよう、リポジトリに Secret を設定します。

設定先のリポジトリに対して作業者アカウントの Admin 権限が必要です。

Settings → Security → Secrets and variables から設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/6a873781-8807-eb68-20e4-bb0db7fc6485.png)

設定する値は下記です。

| Name               | Secret                                              |
| ------------------ | --------------------------------------------------- |
| GH_APP_ID          | GitHub App の ID                                    |
| GH_APP_PRIVATE_KEY | ダウンロードされた GitHub App の pem ファイルの内容 |

ダウンロードされた pem ファイルは GitHub App として接続するパスワードのようなものなので、secret に保存できたら手元から破棄しましょう。

## workflow の作成

Organization の情報を取得するサンプルとして、Organization の Variable を取得する workflow を作成してみます。
下記のファイルを作成し、workflow 作成用の GitHub リポジトリに push します。

`<organization name>` の部分は、Organization 名を記載してください。

```yaml: .github/workflows/get-variables.yaml
name: Get Variables
on:
  workflow_dispatch: {}

jobs:
  get_variables:
    runs-on: ubuntu-latest
    steps:
      - name: Get token
        id: get_token
        uses: actions/create-github-app-token@v1
        with:
          private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
          app-id: ${{ secrets.GH_APP_ID }}
          owner: ${{ github.repository_owner }}

      - name: Get variables
        id: get_variables
        uses: actions/github-script@v7
        with:
          github-token: ${{ steps.get_token.outputs.token }}
          script: |
            const variablesResponse = await github.rest.actions.listOrgVariables({
              org: '<organization name>'
            });
            console.log(variablesResponse.data.variables);

```

なかなかスマートな記述でトークンの取得と Organization 情報の参照ができちゃいます。

`Get token` の step で GitHub App を用いて GitHub のトークンを取得し、そのトークンの値を`Get variables`の step で `github-token:` に引き渡します。

`github.rest.actions.listOrgVariables()` は与えられたトークンを使用して GitHub に問い合わせを行い、結果を返却します。

## workflow の動作確認

動作確認のためには、Organization の Actions secrets and variables の設定で、Organization variables を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/e6e084e2-76ed-bba2-6b0f-2aaee80e8cb3.png)

workflow には `workflow_dispatch` の指定があるので、main マージしていれば GitHub の画面から実行できます。
GitHub リポジトリの Actions の画面から作成した workflow を選択し、 `Run workflow` を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/f5de3d48-4021-a26e-bfc0-7148520b4469.png)

実行後、job の詳細を開いて `Get variables` の内容を見ると、 `console.log(variablesResponse.data.variables);` した結果が見えていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/a11a7891-af71-772a-93b7-5c691252a3e9.png)