
GitHubプルリクエストで特定の承認者によるコードレビューを必須にする:ブランチ保護とCODEOWNERSの実践
チーム開発において、コードの品質を保つために、ブランチへの直接 PUSH を禁止してプルリクエストベースとし、もう一歩進めて、特定の承認者のレビューを通過しないとプルリクエストをマージできないようにする方法を紹介します。
モチベーション
チーム開発において、開発者にリポジトリロールの Write を割り当てると、プルリクエストの作成もマージも自由にできてしまいます。
かといって、カスタムリポジトリロールを検討しても、ReadやWriteといったベースロールに対して一部権限を付与することはできても、ピンポイントにマージ権限は与えないというように、操作を詳細に許可・拒否することはできません。
- https://docs.github.com/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization
- https://docs.github.com/enterprise-cloud@latest/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/about-custom-repository-roles
このような前提のもと、GitHubのブランチ保護ルールとCODEOWNERSを組み合わせて、開発者にコードの変更依頼(プルリクエスト)の自由度をもたせつつ、一部メンバーのみプルリクエストをマージできるようにする方法を紹介します。
特定ブランチへの直接PUSHを禁止してPRベースとする
GitHub フローのような開発フローを取り入れている場合、 main
や develop
のような特定ブランチへの直接PUSH(更新)は禁忌であり、ブランチを切って、プルリクエストベースで修正依頼をします。
GitHubのブランチ保護機能を利用すると、エンタープライズアカウント/組織/リポジトリの粒度で特定ブランチへの直接PUSHを禁止できます。
設定方法
制御したい粒度のブランチルールセットの作成画面に移動します。
組織単位の場合、Repository→Code → Rulesets → New ruleset → New branch rulesetです。
リポジトリ単位の場合、Code and automation → Branches → Add branch ruleset です。
まず、ルールを設定するブランチを "Target branches" で指定します
次に Branch rules の以下を有効にします
- Require a pull request before merging
紛らわしい設定として "Block force pushes" があります。
このオプションは 直接 プッシュではなく 強制 プッシュ($ git push -f
) をブロックするオプションです。
特定の承認者のみPRをマージできるようにする
PRベースの改修ワークフローを強制しても、このフローが形骸化しては意味がありません。
機械的なCIのパス(Require status checks to pass
)等とは別に、コードの取り込みの最終判断は人間の承認を必須にしたいことがあります。コードベースを把握しているシニアなエンジニアなど特定の開発者によるレビューを必須にしてみましょう。
設定方法
先程の "Require a pull request before merging" の詳細設定で、以下を設定します
- 承認者数(
Required approvals
) - コードオーナーの設定(
Require review from Code Owners
)
レビューを必須化
Required approvals
はマージに必要な承認者の数です。
1以上にすることで、レビューを必須にできます。
誰もが承認できると意味をなさないため、レビュアーを制限するのが次で紹介する CODEOWNERS
です。
CODEOWNERS を利用したレビュアーの指定
Require review from Code Owners
をチェックすると、リポジトリ内のファイル .github/CODEOWNERS
でレビュアーを一元管理できます。
このファイルでは、マッチしたファイル/ディレクトリに対して、組織のチームや個人を承認者として指定できます。
レポジトリのコード全体をテックリードチームに委譲するシンプルな運用の場合は、以下の通りです。
# テックリードに委譲
* @sample-org/tech-lead
CODEOWNER
ファイル内の順序は非常に大事です。ドキュメントにもあるように、一番最後にマッチしたルールが適用されるため、下に行くほどルールが具体的になるように記述しましょう("Order is important; the last matching pattern takes the most precedence.")。
# テックリードに委譲
* @sample-org/tech-lead
# JS系ファイルに対して組織のチームでオーナーに指定
*.js @sample-org/js-team
# ディレクトリに対して個別ユーザーアカウントでオーナーに指定
/ios/ @ios-example-foo @ios-example-bar
# 個別ユーザーをメールアドレスで指定
/docs taro@example.com
また、プルリクエストを出した本人は、承認できません。
相互レビューできるように、複数メンバーを承認者に設定しましょう。
後続のレビュアーの自動アサインも考慮すると、CODE OWNERには複数メンバーから成るチームを指定するのが良いでしょう。
参考
- https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
- https://github.com/orgs/community/discussions/6292
レビュアーの自動割当
レビューは時に気の重い作業です。
レビュアーが複数人で構成されていても、お互いに待ち状態だと、いつまでもレビューが進まず、プルリクエストがたまり続けてしまいます。
そこでおすすめなのが、レビュアーの自動割り当てです。
設定方法
チームの Settings 画面で Code review の Enable auto assignment を有効にすると、レビュアーを自動割り当てできます。
割り当てアルゴリズムには、以下の2つから選択できます。
- ラウンドロビン
- ロードバランシング
GitHubのプロフィールステータスで "Busy" をチェックすると、レビュアーにアサインされることは有りません。
まとめ
GitHubのブランチ保護ルールとコードオーナー機能を用い、プルリクエストベースの開発フローを必須とし、PRのマージには特定のレビュアーからの承認を必須にする方法を紹介しました。
ポイントは以下です
- ブランチ保護ルールを用いることで、PR経由のコード変更ワークフローを必須にできる
- コードオーナーを用いることで、PRを承認(マージ)できる開発者を限定できる
- PRの作成者と承認者は別である必要があるため、オーナーは複数名からなるチームを指定するのがオススメ
- チームに対してレビュアーを自動割り当てることも可能
チーム開発の効率と品質のバランスを取りながら、両立させましょう。
参考
- About pull request reviews - GitHub Docs
- CODEOWNERSについて
- GitHubリポジトリにおけるレビュープロセスの統制 | メルカリエンジニアリング
- CODEOWNERSの実際の利用例
- 野村友規(@tmknom) 『GitHub CI/CD実践ガイド』第7章