組織の管理者でもない僕が、組織のプライベートリポジトリにGitHub Appsを使ってPRでreviewdogにコメントさせるまで

## はじめに
組織のプライベートリポジトリに、PRが作られるたびGitHub Actionsを用いてreviewdogにESLintのエラーをコメントさせようと思いました。
しかし、reviewdogの[README.md](https://github.com/reviewdog/action-eslint/blob/master/README.md)に書いてあるようにデフォルトのGitHub Tokenを使っても、そのTokenにはPRへコメントする権限がなかったです（故に、コメントできなかった。。）。

そこで、 **GitHub Apps** を使用する方法を採用することにしました！

ただし、自分は組織の管理者ではないので、 組織にGitHub Appsを作ることもインストールすることもできません。
あーだこーだやって最終的にはできましたが、それなりにつまづいたので、つまづきポイントと共に記事にして供養します！

## 前提知識
- GitHub Apps
    - 公式ドキュメントより「データへのアクセスについてより細やかな権限を提供することから、GitHubとのインテグレーションのための公式に推奨される方式」
    - ref: https://docs.github.com/ja/developers/apps/getting-started-with-apps/about-apps
- GitHub Appsに必要な権限
    - GitHub アプリが API 経由でアクセスできるリソースを定義します
    - リソース一覧は以下から確認できます
    - ref: https://docs.github.com/en/rest/overview/permissions-required-for-github-apps
- GitHub Actions
    - 公式ドキュメントより「ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォーム」
    - ref: https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions
- reviewdog
    - コードを健全に保つために存在する、コードレビューする犬
    - ref: https://github.com/reviewdog/reviewdog

## 個人のトークンではなく、GitHub Appsを使うメリット
- 誰が辞めても継続して動く

## 手順
### 1. GitHub Appsの作成
[Register new GitHub App](https://github.com/settings/apps/new)から、GitHub Appsを作成します。

プロパティは以下の通りです。
- GitHub App name
    - お好みのアプリ名を入れます
- Homepage URL
    - プライベートリポジトリで使う想定なのでここは任意のURLを入れます
- Webhook
    - 不要なのでActiveのチェックを外してください
- Permissions
    - reviewdogがPRにコメントするには以下の権限が必要です
        - check: write
        - contents: read
        - pull-requests: write
            - ref: https://github.com/reviewdog/reviewdog/blob/master/.github/workflows/reviewdog.yml#L53-L55

その他の項目はデフォルト設定のままで構いません。

**公式ドキュメント**

https://docs.github.com/ja/developers/apps/building-github-apps/creating-a-github-app

### 2. GitHub Appsの権限を組織に移譲
1. 先ほど個人で作成したGitHub Appsの詳細画面へ遷移します
2. 左側のサイドバーで詳細設定（Advanced）をクリックします
3. 「Type the name of the GitHub App to confirm」に移譲するアプリ名を、「New owner's GitHub username or organization name」にアプリの権限を移譲したい組織名を入力します
4. 「Transfer this GitHub App」をクリックします
5. 社内のOwner権限をもつ方へ連絡して、承認をしてもらいます

:::note info
この承認依頼から「4. GitHub Appsを使用したいリポジトリにインストール」までの手順は、Owner権限をもつ方に依頼しなければできない可能性があるので、作業手順とともに依頼すると、コミュニケーション回数が減るのでおすすめです
:::

**参考記事**

https://tech.medpeer.co.jp/entry/2022/07/05/114500

**公式ドキュメント**

https://docs.github.com/ja/developers/apps/managing-github-apps/transferring-ownership-of-a-github-app

### 3. GitHub AppsのApp IDとPrivate KeyをGitHubに登録
1. GitHub AppsのApp IDをコピーします
2. GitHub AppsのPrivate Keyを生成して、コピーします
3. GitHubのSecretsにコピーしたApp IDとPrivate Keyを登録します（権限がない場合は、先ほど移譲した時に依頼した人もしくはSecretsの設定ができる社内の誰かへ、依頼します）

:::note warn
僕は間違えてPrivate KeyではなくClient Secretを生成してしまいましたので、間違えないようにしましょう！もし間違えた場合、後述のトークン生成時にエラーが出ます。
ref: https://github.com/tibdex/github-app-token/issues/18#issuecomment-829660844
:::


### 4. GitHub Appsを使用したいリポジトリにインストール
1. [GitHub アプリの設定](https://github.com/settings/apps) ページで、アプリを選択します
2. 左側のサイドバーで、 「アプリのインストール」 をクリックします
3. 適切なリポジトリを含む組織または個人アカウントの横にある 「インストール」 をクリックします
4. すべてのリポジトリ、もしくは選択したリポジトリにアプリケーションをインストールしてください

:::note warn
この作業までOwner権限が必要な可能性があります
:::

**公式ドキュメント**

https://docs.github.com/ja/developers/apps/managing-github-apps/installing-github-apps

### 5. GitHub Actionsにreviewdogが動くステップを追加
以下のステップを GitHub Actions のyamlファイルに追加します。

```yaml
- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@v1
  with: 
    app_id: ${{ secrets.REVIEDOG_APP_ID }} # ここは先ほどSecretに登録したApp IDのkeyを入力
    private_key: ${{ secrets.REVIEDOG_PRIVATE_KEY }} # ここは先ほどSecretに登録したPrivate Keyのkeyを入力
- uses: reviewdog/action-eslint@v1
  with:
    github_token: ${{ steps.generate_token.outputs.token }}
    reporter: 'github-pr-review'
```

独立して動かしたい場合は、以下のコードをコピペして試してください！

```yaml
name: reviewdog for eslint
on: [pull_request]
jobs:
  eslint:
    name: run reviewdog for eslint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@v1
        with: 
          app_id: ${{ secrets.REVIEDOG_APP_ID }}
          private_key: ${{ secrets.REVIEDOG_PRIVATE_KEY }}
      - uses: reviewdog/action-eslint@v1
        with:
          github_token: ${{ steps.generate_token.outputs.token }}
          reporter: 'github-pr-review'
```

:::note warn
このyamlファイルを定義して、GitHub Actionsが走っても、実際にはコメントされない可能性があります。`Read and write access to checks, code, and pull requests` という文言を含んだ要求メールが管理者に飛んでいるかもしれません。確認しましょう。
:::

## まとめ
いかがだったでしょうか！
PRにコメントを追加させるために、管理者権限を持っていないがために、少し余分にステップを踏まなきゃいけず、大変でした。。管理者の方の時間もとってしまうため、できるだけ全体の流れを把握してから依頼ができるよう、まとめてみました。誰かのお役に立てれば幸いです :bow: