AQ Tech Blog

次世代ブランチ保護ルール リポジトリルールについて | AQ Tech Blog

作成者: yoshihiro.sato|2023年04月21日

はじめに

GitHubにおける次世代のブランチ保護ルール「リポジトリルール」がパブリックベータになりましたね!
ブランチ保護ルールとの違いは以下の点に注目してみると分かりやすいかと思います。

 

  ブランチ保護ルール リポジトリルール
対象 ブランチ ブランチおよびタグ
1つの対象に複数のルールを同時に適用 できない できる
閲覧に必要なロール 管理者 読み取り
作成、編集および削除に必要なロール 管理者 管理者
ルールの無効化 できない(削除はできる) できる

1. 対象

ブランチ保護ルールでは名前の通り対象はブランチに限られていましたが、リポジトリルールではタグを対象に出来るようになりました。
これにより、リリースにもルールを適用できるようになりました。

2. 1つの対象に複数のルールを同時に適用

ブランチ保護ルール

ブランチ保護ルールでは1つの対象(ブランチ)に対して、ルールは1つしか適用できません。
1つの対象に影響を与える複数のルールがある場合は優先度が計算され、最も高いルールのみが適用されます。

優先度は高いものから

  1. 特定のブランチ名
  2. *, ?, ]などの特殊文字が含まれたパターン

となっており、同一優先度の中では作成された日付が古いものが最も優先されます。

 

優先度の動作確認

特殊文字が含まれたパターンよりも特定のブランチ名が優先される

同一優先度の中では作成日時が古いものが最も優先される

リストの中で上にあるものが古いルールです。

 

 

リポジトリルール

リポジトリルールには優先度の概念がなく、かわりに階層化という仕組みがあります。

階層化

複数のルールセットが同じブランチまたはタグを対象とする場合、各ルールセットは集約されます。
そして集約された各ルールセットに同じルールが異なる内容で定義されていた場合、最も制限の厳しいルールが適用されます。

階層化はリポジトリルールだけでなく、同じブランチまたはタグを対象とする保護ルールもその対象となります。

階層化の動作確認
  ブランチ保護ルール1 ブランチ保護ルール2 リポジトリルール
ターゲットパターン mai* main* ma*
作成順 1 2 3
必要な承認の数 1 2 3

ブランチ保護ルールの優先度に従えば必要な承認の数は1となるはずですが、
階層化の仕組みが働き、必要な承認の数は3となっています。

では、リポジトリルールの制限を緩めてみた場合はどうなるのでしょうか。

  ブランチ保護ルール1 ブランチ保護ルール2 リポジトリルール
ターゲットパターン mai* main* ma*
作成順 1 2 3
必要な承認の数 1 2 0

もっとも厳しい必要な承認の数ルールはブランチ保護ルール22ですが、実際には1となっています。
ここから、ブランチ保護ルールを優先度で絞り込んだ上でリポジトリルールと集約されていることが分かります。

3. 閲覧に必要なロール

ブランチ保護ルールは閲覧にも管理者ロール(またはリポジトリルールの編集権限を持つカスタムロール)が必要となります。
一方、リポジトリルールは読み取りロールがあればアクティブなルールセットを閲覧できます。

Anyone with read access to a repository can view the active rulesets for the repository. This means a developer can understand why they have hit a rule, or an auditor can check the security constraints for the repository, without requiring admin access to the repository.
(リポジトリへの読み取りアクセス権を持つユーザーは、リポジトリのアクティブなルールセットを表示できます。これは、開発者がルールにヒットした理由を理解できること、または監査人がリポジトリへの管理者アクセスを必要とせずに、リポジトリのセキュリティ制約を確認できることを意味します。)

引用元

4. 作成、編集および削除に必要なロール

ブランチ保護ルール、リポジトリルールのどちらも管理者ロール(またはリポジトリルールの編集権限を持つカスタムロール)が必要となります。

5. ルールの無効化

ブランチ保護ルール

ブランチ保護ルールには有効・無効を切り替える機能がないため、無効化するには以下の方法が考えられます。

  1. ルールを削除する
  2. ルールを編集し、個別の内容をオフにする
  3. より優先度の高いルールを作成する

1、2は単純ですが破壊的です。GitHubアプリを利用するなどして設定をコード化することが望ましいでしょう。
3は非破壊的ですが、既に優先度が最高のルールに対しては無力です。

 

リポジトリルール

リポジトリルールにはステータスがあり、簡単に有効/無効(評価)を切り替えることができます。

 

余談

ブランチ保護ルールのREST APIはブランチリソースに対して紐づくため、以下の欠点がありました。

  • 存在しているブランチに対してのみ定義できる
  • *などの特殊文字を使用できない

GraphQL APIで上記の欠点は改善されていたのですが、GraphQL APIはグローバルノードIDとユーザーフレンドリーなIDとのギャップがあり、銀の弾丸ではなかったように感じました。(IDの変換に関わるOSSのバグなどもあり)

しかしリポジトリルールのREST APIでは、リポジトリにルールが紐づいている自然な構造のおかげでとても使いやすくなっておりました!ありがとうGitHub!

参考

Introducing Repository Rules Public Beta | GitHub Changelog

About rulesets - GitHub Docs

Managing a branch protection rule - GitHub Docs

Organizationのリポジトリロール - GitHub Docs