GitHub ActionsでChecksを実行できるPull Requestを作成する

デフォルトのGITHUB_TOKENでPull Requestを作成した場合、そのPull RequestにフックするはずのGitHub Actions(Checks)が実行されない。

そのため以下のどちらかの方法でトークンを取得する必要がある。

  • GitHub Appsを使用してトークンを取得する
  • Personal Access Token(PAT)を作成して与える

本記事では、GitHub Appsを使用してPull Requestを作成する。

GitHub Apps

トークンを生成するためのGitHub Appsを作成する。
GitHub Appsの設定のポイントは以下の通り。

Permission

Repository Permissionの設定で以下の権限を有効化する。

  • contents: read and write - リポジトリの内容を変更するために必要
  • pull-requests: read and write - Pull Requestを作成するために必要

Private key

GitHub AppsのGeneralの設定でPrivate Keyを生成し、控えておく。
似た設定にClient secretsがあるが、Private Keyの設定はその下のほうにあるので注意する。

Install

利用するアカウントもしくはOrganizationにGitHub Appsをインストールする。
必要に応じてリポジトリを選択し、そのリポジトリだけで利用できるようにする。

VariablesとSecrets

GitHub Appsを利用するリポジトリで以下のVariablesとSecretsを設定する。

  • Variables
    • GH_APP_ID - 上記で作成したGitHub AppsのIDを設定する
  • Secrets
    • GH_APP_PRIVATE_KEY - 上記で控えておいたPrivate Keyを設定する

private keyは機密情報なのでGitHubのSecretsに設定する必要がある。
App IDも隠したければGH_APP_IDとしてSecretsに設定してもよい。

これらの設定は、GitHub Actionsのワークフローで使用する。

GH_APP_ID${{ vars.GH_APP_ID }}のように参照できる。
Secretsに設定した場合は${{ secrets.GH_APP_ID }}のように参照する。
GH_APP_PRIVATE_KEY${{ secrets.GH_APP_PRIVATE_KEY }}のように参照できる。

ワークフロー

Pull Requestを作成するワークフローは以下のとおり。

name: Create Pull Request

on:
  workflow_dispatch:
    inputs:
      branch-name:
        description: 'branch name to create'
        required: true
        default: 'test-branch'

permissions:
  contents: write
  pull-requests: write

jobs:
  pr:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
    # リポジトリのコードをチェックアウト
    - name: Checkout code
      uses: actions/checkout@v4

    # GitHub App のトークンを生成
    - name: Generate token
      id: generate_token
      uses: actions/create-github-app-token@v2
      with:
        app-id: ${{ vars.GH_APP_ID }}
        private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}

    # Botアカウントでコミットするための設定
    - name: Configure git
      run: |
        git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --global user.name "github-actions[bot]"        

    # コミット内容は適当
    - name: Commit changes
      run: |
        git switch -c "$BRANCH_NAME" origin/main
        echo "test" >> README.md
        git add README.md
        git commit -m "Add line to README.md"
        git push origin HEAD        
      env:
        BRANCH_NAME: ${{ github.event.inputs.branch-name }}

      # GitHub App のトークンを使用して Pull Request を作成
    - name: Create pull request
      run: |
        gh pr create --title "Add line to README.md" --body "This PR adds a line to README.md"        
      env:
        GH_TOKEN: ${{ steps.generate_token.outputs.token }}

ポイントは以下の通り。

permissions

permissions セクションでワークフローが必要とする権限を設定する。

GitHub Appsで指定した権限をここでも指定する必要がある。

contents: write はリポジトリの内容を変更するために必要で、コミットとプッシュを行うために必要となる。

pull-requests: write はPull Requestを作成するために必要となる。

actions/create-github-app-token

actions/create-github-app-token アクションでGitHub Appのトークンを生成する。このトークンは、Pull Requestの作成やコミットのプッシュなど、GitHub APIを使用するために必要となる。

Configure git

git config コマンドでGitのユーザー名とメールアドレスを設定する。
このGitHub Actionsでは、GitHub Appsのボットアカウントを使用してコミットしている。

» 参考: Github Actionsでコミットを作る

gh pr createコマンドの前にpushしておく

gh pr create コマンドでinteractiveモードではない方法でPull Requestを作成するために、事前に変更をpushしておく必要がある。
そのため上記の例では、git push origin HEAD を実行して、変更をリモートリポジトリにプッシュしている。

Create pull request

gh pr create コマンドを使用してPull Requestを作成する。
GH_TOKENにGitHub Appsから取得したトークンを設定することで、GitHub APIを使用してPull Requestを作成できる。

Pull Requestにフックするワークフロー

Pull Requestにフックするワークフローは、pull_requestイベントで起動するように設定する。
例えば以下のように設定する。

name: CI

on:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '16'

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

ワークフローの実行

上記の例ではdispatch_workflowイベントで起動するように設定したため、GitHubのActionsタブから手動で実行できる。
pull_requestpushイベントで起動するように設定すれば、Pull Requestの作成やコードのプッシュ時に自動的に実行される。

作成されたPull RequestではPull Requestにフックするワークフローが実行され、Checksが表示されるようになる。