github actionsでPRを自動作成したけどbranch protection用のジョブがトリガーされない


# はじめに
[前回の記事](https://qiita.com/itouoti/items/81c64d46c74baaba075c)で、AWS API GatewayのSDKを自動更新するパイプラインを作成しました。
その際にパイプラインからPRを作成しました。
そして、PRを作成したOrganization repositryにbranch protectionを設定していました。
branch protectionの内容としては、PRが作られたタイミングでprotection用のジョブがトリガーされ、正常終了したPRのみがmergeできるという設定です。
で、今回発生した問題が、
github actions経由で作成したPRに対して、protection用のジョブがトリガーされなかった。
そのため、mergeがblockされ続ける というものです。

解決したので記事に残します。

# 環境
- Organizationのgit repository
- repositoryにはbranch protectionが設定されている
- branch protectionは以下の条件で設定されている
    - 最低一人のreview approveが必須
    - protection用のjobがそのPRに対して実行され、正常終了していること
- github actionsからPRを自動作成した

# 何が起きたのか

- 作成されたPRに対してbranch protectionで設定しているjobが起動しなかった(以下の状態がずっと)
    ![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/b4f92b5b-b66a-f488-dc2f-6c9178a2cdea.png)


    - `Expected — Waiting for status to be reported`とあるのでbranch protectionのjobの正常終了を待っている状態
    - もちろん`Merge pull request`は押せない

# 原因
[stack overflowの投稿](https://stackoverflow.com/a/69169858)で書いてくれている人がいるのですが、
- `${{ secrets.GITHUB_TOKEN }}`で使用することが出来る[GITHUB_TOKEN](https://docs.github.com/ja/actions/security-guides/automatic-token-authentication)の権限では、github actionsのパイプラインから、他のgithub actionsのパイプラインをトリガーすることは制限されている
- そのため、GITHUB_TOKENを使って作成されたPRに対して、branch protectionのジョブをトリガーすることが出来ず、branch protectionがずっと待ち状態になる

# 解決方法
今回試した解決方法は「簡単な暫定解決」と、「ちょっとひと手間だけど根本解決」の2つあります。

## 簡単な暫定解決

- PRに対しての最後の操作を人間にする
  - 自動作成されたPRに対して空commitをpushする
  - 自動作成されたPRを一旦closeし、reopenする

要は以下のようになればいい
![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/1b2a58b1-e232-edba-942e-5c07a871da5c.png)


github に追加の設定を入れないのですぐ対処できる。簡単。
だけど自動作成したPRをそのままポチッとmerge出来ないのでちょっと面倒。

### 自動作成されたPRに対して空commitをpushする
- `git commit --allow-empty && git push`

### 自動作成されたPRを一旦closeし、reopenする
- closeして、reopen
![1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/c90a2752-a192-e192-80dc-d51692ed768f.png)


## ちょっとひと手間だけど根本解決
- PR作成時のgithub CLIを使う権限を強くする

organizationにgithub appsを連携させて、git appsのtoken権限を利用する方法
githubに権限設定を加えるので、セットアップが面倒くさい。
だけど自動作成したPRをそのままポチッとmerge出来るので理想形。
organizationでPATの利用を許可して使う方法もありますが、個人に紐づく情報はそもそもorganizationにおいては使わないほうがいいです。
なので個人に紐づかないgithub appsを使います。

### GitHub AppsのOrganizationとの連携
- [こちらの記事](https://studist.tech/migration-to-github-apps-c2752d506d9a)がよくまとまっているので導入方法は割愛します。
- github AppsをOrganizationと連携させるのはOrganizationのオーナー/管理者に設定して貰う必要がある。
- PRに対してのwrite権限はつける
    ![1-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/0295d544-17ee-a2e4-1837-730ee8eb4b5e.png)

- 最終的なGithub Appsの設定
    ![1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/60b89f86-ed05-5638-8961-a5409f7d51cd.png)

- `App ID`と`Private Key`をsecretsに登録しておく

### pipeline.yamlの設定
[前回の記事](https://qiita.com/itouoti/items/81c64d46c74baaba075c)で使ったyamlの修正差分で表す

```diff_yaml

name: update api gateway sdk

on:
    ...
env:
  SYNC_BRANCH: hotfix/apigateway_sdk_update
-  GH_TOKEN: ${{ github.token }}
  SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

permissions:
  id-token: write
  contents: write
  pull-requests: write

jobs:
  build:
    name: get sdk 
    runs-on: ubuntu-latest

    steps:

+     - name: Generate token
+       id: generate_token
+       uses: tibdex/github-app-token@v1
+       with:
+         app_id: ${{ secrets.APP_ID }}
+         private_key: ${{ secrets.PRIVATE_KEY }}

+     - name: tokenの設定
+       run: |
+         echo GH_TOKEN=${{ steps.generate_token.outputs.token }} >> "$GITHUB_ENV"

      - name: Checkout
        uses: actions/checkout@v3
+       with:
+         token: ${{ env.GH_TOKEN }}

        ...

      - name: ブランチ作成/更新
        id: create-sync-branch
        if: env.NEW_SDK_CHECKSUM != env.OLD_SDK_CHECKSUM
        run: |
          git config user.email "actions@github.com"
          git config user.name "Github Actions"
          branch=${{ env.SYNC_BRANCH }}
          git switch -C $branch
          git add .
          git commit -m "update AWS API Gateway SDK from Github actions"
          git push -f origin $branch

      - name: PR作成済みチェック
        id: check_pr
        if: env.NEW_SDK_CHECKSUM != env.OLD_SDK_CHECKSUM
        run: |
          pr_title='API Gateway SDK new Update🚀'
          base_branch='master'
          echo "::set-output name=count::$(gh pr list -S "${pr_title}"' in:title' -B $base_branch | wc -l)"
          echo "::set-output name=pr_title::$pr_title"
          echo "::set-output name=base_branch::$base_branch"

      - name: PR作成
        if: ${{ (env.NEW_SDK_CHECKSUM != env.OLD_SDK_CHECKSUM) && (steps.check_pr.outputs.count == 0) }}
        env:
          TZ: 'Asia/Tokyo' # タイムゾーン指定
        run: |
          CURRENT_DATETIME=$(date +'%Y-%m-%d %H:%M:%S')
          gh pr create -B ${{ steps.check_pr.outputs.base_branch }} -t "${{ steps.check_pr.outputs.pr_title }}" -b "🕰️make PR date: $CURRENT_DATETIME" 
```

### ポイント
#### Generate token
```yaml
    - name: Generate token
      id: generate_token
      uses: tibdex/github-app-token@v1
      with:
        app_id: ${{ secrets.APP_ID }}
        private_key: ${{ secrets.PRIVATE_KEY }}

    - name: tokenの設定
      run: |
        echo GH_TOKEN=${{ steps.generate_token.outputs.token }} >> "$GITHUB_ENV"
```
- Github Appsからtokenを生成し、GH_TOKENとして設定している。
- `gh pr create`でのPR作成に影響を与える(Github Apps権限での作成になる)

#### Checkout
```yaml
    - name: Checkout
      uses: actions/checkout@v3
      with:
        token: ${{ env.GH_TOKEN }}
```
- Github Appsから生成したtokenをリポジトリのcheckout時に指定している
- `git push`を始めとした`git`コマンドに影響を与える(Github Apps権限での操作になる)
- 逆にこれを設定しないと`git push`はただのgithub actions権限での操作扱いになる
- その場合、PRに対して後から`force push`をした時にbranch protecionはトリガーされない
    ![1-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641313/767c92db-ad10-6c74-395d-b188bf2ece11.png)


# まとめ
暫定的な対応でも正直全然許容レベルかなと思いましたが、パイプラインとしての理想を追い求めてみました。

# 参考
- [Github pull request - Waiting for status to be reported](https://stackoverflow.com/questions/52200096/github-pull-request-waiting-for-status-to-be-reported)
- [Personal Access TokenからGitHub Appsに移行する](https://studist.tech/migration-to-github-apps-c2752d506d9a)