Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

GitHub Actionsで特定のブランチへのプルリクだけレビュワーをランダムに抽選してみた

あまり聞き慣れないインテグレーションエンジニアという職種の尾宇江です!

今回は、GitHub Actions と GitHub Teamsのauto assignmentで、特定のブランチに向けたプルリクだけレビュワーをランダムに抽選してみた件を紹介します。

やりたかったこと

「プルリクのレビューはランダムで振り分けたいけど、developブランチからstagingなど機械的にマージする時はレビュワーつけたくないなー」

事前に調べた内容と課題整理

  • GitHub Teamsに、auto assignmentという、チームメンバーに均等にレビューを割り当てるすごい機能がある!
  • codeownersを使えば、プルリクがオープンされた時に自動的にレビュワーをつけることができる!
    • @organization/team のように指定すれば、チームをコードオーナーに指定することもできる

↑の2つを組み合わせれば、ほぼコード書かずにレビュワーのランダム振り分けができるなって思ったのですが…
コードオーナーではディレクトリやファイル名の指定はできるものの、ブランチの指定ができませんでした。

作ったもの

ということで、GitHub ActionsでブランチをチェックしてからTeamにレビュー依頼をすることにしました。
以下のファイルを.github/workflows/request_reviewer.yml として保存しています。

今回は、feature/**_dev といったブランチから、delivery/* というブランチへのプルリクが作成された or ドラフトから レビューOKとなったタイミングで、developer というチームにレビューリクエストを投げています。

また後述の理由により、GitHubのREST APIを叩く際には、Actionsで最初から使える secrets.GITHUB_TOKEN ではなく、個人アカウントで発行したパーソナルアクセストークンリポジトリの環境変数に保存して使っています。

name: Request a Reviewer
on:
  pull_request:
    types: [opened, ready_for_review]
    branches:
     # ここで指定するのは、PRの入れ先となるブランチです
      - "delivery/*"

jobs:
  assign:
    runs-on: ubuntu-latest
    # 入れ元となるブランチの指定をgithub.head_refを利用
    # プルリクがドラフトだった場合はレビュー依頼しないように、pull_request.draft でチェック
    if: ${{ (startsWith(github.head_ref, 'feature/') || endsWith(github.head_ref, '_dev')) && github.event.pull_request.draft == false }}
    steps:
      - name: Auto Assign
        run: |
          curl -X POST \
            -H "Accept: application/vnd.github.v3+json" \
            -H "Authorization: token ${{ secrets.PERSONAL_ACCESS_TOKEN }}" \
            -d "{ \"team_reviewers\": [\"developer\"] }" \
            https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers

おまけ

REST APIでパーソナルアクセストークンを使っている理由

-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ を使ってActionsからREST APIを実行した場合、以下のようなエラーとなってしまいました。

{
  "message": "Validation Failed",
  "errors": [
    "Could not resolve to a node with the global id of 'xxxxxxxx'."
  ],
  "documentation_url": "https://docs.github.com/rest/reference/pulls#request-reviewers-for-a-pull-request"
}

上記のエラーでハマったのですが…
GitHub APIのバグじゃないかなって言ってるIssueを参考にパーソナルアクセストークンを発行して対応しました。

GitHub CLIを使わなかった理由

GitHub CLIを使うと

 - run: gh pr edit $NUMBER --add-reviewer @organization/developer
    env:
      GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      GH_REPO: ${{ github.repository }}
      NUMBER: ${{ github.event.pull_request.number }}

のようにシンプルに書けていいなと思ったのですが…

GraphQL: Your token has not been granted the required scopes to execute this query. The 'login' field requires one of the following scopes: ['read:org'], but your token has only been granted the: ['repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens., Your token has not been granted the required scopes to execute this query. The 'name' field requires one of the following scopes: ['read:org', 'read:discussion'], but your token has only been granted the: ['repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens., Your token has not been granted the required scopes to execute this query. The 'slug' field requires one of the following scopes: ['read:org', 'read:discussion'], but your token has only been granted the: ['repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens.

のようなエラーが出てしまいます。 こちらはGitHub CLIの既知のバグらしく次回のリリースで解消されるようなので、その時にはCLIで書き直そうと思いますー。

チームの指定方法

REST APIの場合は reviewers ではなくて、team_reviewers でチーム名を指定。
@organization/developer の場合は、developer だけ
GitHub CLIの場合は、--add-reviewer@organization/developer のように組織/チーム名という組み合わせで指定するという違いにもハマりました。