保護されたブランチをベースとした Pull Request に対するレビューの承認が却下される条件を確認してみた

2023.11.13

こんにちは、CX 事業本部 Delivery 部の若槻です。

GitHub では、指定のブランチへの push に条件を設けることができるブランチ保護ルール(Branch protection rule)という機能があります。

下記のようなメニューで指定のパターンに一致するブランチをベースとした Pull Request のマージに対して承認レビューやステータスチェックの合格を必須とすることにより、意図しない変更がコードに混入することを防ぐことがでます。

そして上記のうち「最後の push が追加される前に行われていた承認レビューは却下する」という条件の適用は、下記の 2 つのいずれかを有効化することで実現できます。

  • Dismiss stale pull request approvals when new commits are pushed

New reviewable commits pushed to a matching branch will dismiss pull request review approvals.

  • Require approval of the most recent reviewable push

Whether the most recent reviewable push must be approved by someone other than the person who pushed it.

今回は、実質同じである上記条件の有効化の有無によって、保護されたブランチをベースとした Pull Request に対するレビューの承認が却下される条件がどのように変わるのか?を特定のケースにおいて確認してみました。

承認の却下条件を確認したいケース

Pull Request を利用した開発作業において「ある Pull Request のマージを待たずにそのブランチの変更をもとに別の Pull Request を作成したい」というケースが時々あります。その場合は、例えば feature1 から保護されたブランチ main への Pull Request と、feature2 から feature1 への Pull Request が下記のようなマージ方向で作成されることになります。

main(保護されたブランチ)<- feature1 <- feature2

このケースの場合に、前述の 2 つのブランチ保護条件の有効/無効に応じて「最後の push が追加される前に行われていた承認レビューは却下」される挙動はどのように変わるのでしょうか。

確認方法

確認は下記の手順で行いました。

  1. 保護されたブランチ main をベースとした feature1 ブランチの Pull Request を作成する
  2. feature1 ブランチをベースとした feature2 ブランチの Pull Request を作成する
  3. feature1 および feature2 ブランチの Pull Request に対してレビュアーによる承認を行い、マージ可能な状態にする
  4. feature1 ブランチの Pull Request をマージする
  5. feature2 ブランチの Pull Request がマージ可能であるか確認する

結果

確認結果は以下のようになりました。2 つの条件をいずれも無効にしなければ、「最後の push が追加される前に行われていた承認レビューは却下」される挙動となりました。

結果 Dismiss stale pull request approvals when new commits are pushed Require approval of the most recent reviewable push
却下された 有効 有効
却下された 無効 有効
却下された 有効 無効
却下されなかった 無効 無効

ドキュメントを読む

ドキュメントを読むと、この挙動は仕様として記載されていました。「マージ ベースに新しい変更が導入された場合」というのが、ベースブランチが保護ブランチにマージされた場合にも該当するようです。

Note: If you select Dismiss stale pull request approvals when new commits are pushed and/or Require approval of the most recent reviewable push, manually creating the merge commit for a pull request and pushing it directly to a protected branch will fail, unless the contents of the merge exactly match the merge generated by GitHub for the pull request.

In addition, with these settings, approving reviews will be dismissed as stale if the merge base introduces new changes after the review was submitted. The merge base is the commit that is the last common ancestor between the topic branch and the base branch. If the merge base changes, the pull request cannot be merged until someone approves the work again.

(日本語訳)
注: [新しいコミットがプッシュされたときに古いプル リクエストの承認を破棄する] または [最新のレビュー可能なプッシュの承認を要求する] を選択した場合、プル リクエストのマージ コミットを手動で作成して保護されたブランチに直接プッシュすることは失敗します。 ただし、マージの内容が、プル リクエストに対して GitHub によって生成されたマージと正確に一致する場合を除きます。

さらに、これらの設定では、レビューの送信後にマージ ベースに新しい変更が導入された場合、承認レビューは古いものとして無視されます。 マージ ベースは、トピック ブランチとベース ブランチの間の最後の共通の祖先であるコミットです。 マージ ベースが変更された場合、誰かが作業を再度承認するまでプル リクエストはマージできません。

おわりに

保護されたブランチをベースとした Pull Request に対するレビューの承認が却下される条件を確認してみました。

Dismiss stale pull request approvals when new commits are pushed または Require approval of the most recent reviewable push のいずれかの条件を有効化した場合に、ベースブランチのマージによりヘッドブランチ側の Pull Request での承認レビューが却下される挙動となることを確認しました。

main(保護されたブランチ)<- feature1 <- feature2 のようなマージ方向で Pull Request を作成する際には追加の承認レビューを要求する必要があるので留意するようにしましょう。

以上