GitHub の Repository Rules を試してみる
これ
Introducing Repository Rules Public Beta | GitHub Changelog
Changelog を読む
もちろん DeepL Pro 先生が活躍。
前文
- リポジトリルールはブランチ保護の進化系
 - 大規模なリポジトリでより安全でコンプラに準拠したリポジトリにすることを支援
 - ルールによってリポジトリ内のブランチやタグの保護を簡単に定義
 - GHECの顧客ならOrganization全体でそれを強制可能
 - リポジトリを読める全ての人がどのようなルールがあるのかを知ることも容易
 
ルールの作成
- ルールの中核をなすのはルールセットを定義する機能
 - ルールセットとは、一緒に実施されるルールの集合体
 - 例:あるブランチへのコミットは署名付きで、そのコミットには2人のレビュアーがいることを要求
 - ルールセットはタグに適用でき、リリースにルールを適用することができる
 - ルールセットページはリポジトリの全てのルールを表示・管理するための中心
 - 新しいルールセットの追加や既存のルールセットの編集が可能
 - ルールセットには
enforcement statusがある- 
activeはコミットをマージするためにパスする必要がある - 
disabledはルールセットが強制されない。マージを妨げることはない。管理者はルールを強制する前にルールを作成できる 
 - 
 - ルールセットでブランチやタグを対象とすることは容易で、便利な選択肢がある
- デフォルトブランチ
 - 全てのブランチ
 - fnmatchパターンにマッチするブランチやタグ
 
 - ルールセットに複数のパターンを追加して異なるブランチやタグの命名スタイルに適用もできる
 
ルールを表示する
- リポジトリにアクセスできる人なら誰でもルールと意味を見ることができる
 - ルールセットの概要はブランチページで盾のアイコンをクリックすると表示される
 - プルリクエストやルールがプッシュをブロックした時の Git CLI の出力からリンクされている
 - ブランチやタグでルールをフィルタリングして次のプッシュでルールがどのように実行されるかを理解できる
 
Getting Started
- リポジトリルールは GitHub Cloud の全ての顧客が利用可能
 - ドキュメント
 
korosuke613/playground で試してみる
/settings/rulesから行ける。

ブランチとタグを作成時に選ぶ。


- General
- Name
- ルールセット名を表す
 
 - Enforcement status
- 有効(
Active)か無効(Disabled)か選ぶ - デフォルト無効
 
 - 有効(
 - Bypass mode
- ルールセットを無視できる人を指定する
 - デフォルトで
Not permitted。誰も無視できない - もしくは
Repository bypass permitted。次の人物がバイパスできる- Organization Administrators
 - Repository Administrators
 - リポジトリバイパス権限を持つユーザ
 
 
 
 - Name
 - Bypass list
- チームまたはアプリをバイパスリストに追加することでルールセットを無視できる
 - 人(user)は選べなさそう
 
 - Target branches
 - Branch protections
- ブランチをどのように保護するか。チェックボックス形式
 - 別で詳しく書く
 - 従来のブランチ保護とほぼ一緒(参考)
 - 選択肢
- Restrict creations: ブランチの作成を禁止
 - Restrict updates: ブランチの更新を禁止
 - Restrict deletions: ブランチの削除を禁止(デフォルトtrue)
 - Require linear history: merge commit を禁止
 - Require deployments to succeed before merging: マージ前にデプロイメントの成功を必須とする
 - Require signed commits: コミット署名を必須とする
 - Require a pull request before merging: プルリクエストからのマージを必須とする
 - Require status checks to pass before merging: 指定した checks のパスを必須とする
 - Block force pushes: force push を禁止
 
 
 
conventional commitの強制ができるmetadata restrictionsは個人では使えないらしい。
試しに、try-rulesets/**/*にマッチするブランチに対するルールセットを作った。
branch protections は Restrict creations、Restrict deletions、Block force pushes のみ。
createを禁止してるのでpushできないはず。
❯ git switch -c try-rulesets/hoge
Switched to a new branch 'try-rulesets/hoge'
❯ git commit --allow-empty -m "try: ruleset プッシュできない"
[try-rulesets/hoge 65a3b6d] try: ruleset プッシュできない
❯ git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 460 bytes | 460.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: GH006: Protected branch update failed for refs/heads/try-rulesets/hoge.
remote: error: Cannot create ref due to create name restrictions
To https://github.com/korosuke613/playground
 ! [remote rejected] try-rulesets/hoge -> try-rulesets/hoge (protected branch hook declined)
error: failed to push some refs to 'https://github.com/korosuke613/playground'
おー失敗した。
GH006: Protected branch update failed for refs/heads/try-rulesets/hoge.
Cannot create ref due to create name restrictions
理由もちゃんと出てるね。
Bypass mode を Repository bypass permitted にしてみる。
git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 460 bytes | 460.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Bypassed rule violations for refs/heads/try-rulesets/hoge:
remote:
remote: - Cannot create ref due to create name restrictions
remote:
remote:
remote: Create a pull request for 'try-rulesets/hoge' on GitHub by visiting:
remote:      https://github.com/korosuke613/playground/pull/new/try-rulesets/hoge
remote:
To https://github.com/korosuke613/playground
 * [new branch]      try-rulesets/hoge -> try-rulesets/hoge
branch 'try-rulesets/hoge' set up to track 'origin/try-rulesets/hoge'.
ちゃんと送れた。
個人だとそこまでできることはブランチ保護と変わらないかな。
次はGHECの方でやってみよう。
GHEC (会社のリポジトリ) で試してみる
まずはルール作成。
基本は個人の設定と一緒。
ただ、いくつか違う点がある。
- General
- Enforcement status
- 
Disabled、Activeに加えてEvaluateが増えている - Evaluate にするとルールは強制されないが、Insights ページからルールセットがアクティブであった場合に合格または失敗を確認できる(参考)
 
 - 
 
 - Enforcement status
 - Metadata restrictions
- 個人向けにはなかった項目
 - コミットのメタデータについての制限をかけられる
 - 次の選択肢を掛け合わせる
- Applies To: 対象
- Commit message
 - Author email
 - Committer email
 - Branch name
 
 - Requirement: 要件
- パターンと前方一致する
 - パターンと後方一致する
 - パターンが含まれる
 - 正規表現とマッチする
 - パターンと前方一致しない
 - パターンと後方一致しない
 - パターンが含まれない
 - 正規表現とマッチしない
 
 - Matching pattern: パターンを記述
 - Description: 概要を記述
 
 - Applies To: 対象
 
 
作った。
評価モードで、コミット署名必須&コミットメッセージが^EPT-[0-9X]*: .*に一致しないといけないルール。
コミットメッセージは例えばEPT-2023: 新年だよみたいな。
- Enforcement status: 
Evaluate - Bypass mode: 
Not permitted - Bypass list: なし
 - Target branches
try-rulesets/**/*
 - Branch protections
Require signed commits
 - Metadata restrictions
- 
Commit message,Must match a given regex pattern,^EPT-[0-9X]*: .* 
 - 
 
try-rulesets/no-signedブランチを作成。
適当にコミット。
commit b2df73681db63831a8ec9ef5db26331c0523ec93 (HEAD -> try-rulesets/no-signed, origin/try-rulesets/no-signed)
Good "git" signature for hogehoge@hoge with ED25519 key SHA256:eZvqeOd02bzO1Tz1pTv1mq6KH4z2hGO0BoPhknpqfCE
Author: Futa HIRAKOBA <hogehoge@hoge>
Date:   Wed Apr 19 14:10:58 2023 +0900
    EPT-2023: 新年だよ
プッシュ。
Rule Insights を見に行く。

お〜〜 Pass してるねぇ。

詳細も見れる。
今度はルールに反するコミットをpushしてみる。
コミットメッセージのルールを無視した。

ちゃんと Fail になった。

理由もコミットメッセージがダメってでる。
署名が必須のルールを無視した。
コミット時に--no-gpg-signをつけて署名を外す。

ちゃんと Fail になった。

理由も署名がないってでる。
GHEC で Organization 単位のルールセットを試してみる
Organization 単位でのルールセットの設定はどう変わるか。
場所は同じく URL 的には settings/rules。UI 的には Repository -> Repository rulesets。
基本は GHEC のリポジトリ単位の設定と同じ。
違う部分として、リポジトリの絞り込みが追加されている。
- Target repositories
- 対象リポジトリを追加する
 - 追加の選択肢
- Include all repositories
 - Include by pattern
 - Exclude by pattern
 
 - Prevent renaming of target repositories
- リポジトリ名の変更を禁止する
 - デフォルトfalse
 - trueにするとバイパスできる人のみ変更できるようになる
 
 
 
今回はブランチ名を強制するルールを作ってみる
- Target repositories
- 任意のリポジトリを指定
 
 - Target branches
- 今回はブランチ名の制約なので、
All branchesを追加 
 - 今回はブランチ名の制約なので、
 - Branch protections
- 全てチェックを外す
 
 - Metadata restrictions
- Applies To: 
Branch name - Requirement: 
Must match a given regex pattern - Matching pattern: 
EPT-[0-9X]*\/.* 
 - Applies To: 
 
EPT-2023/happy-new-year みたいなブランチ名しか受け付けない設定。

ちゃんとどのリポジトリが対象かも出てきていいね
hogeというブランチを作って push してみる。
❯ git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 262 bytes | 262.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: GH013: Repository rule violations found for refs/heads/hoge.
remote: Review all repository rules at http://github.com/<org名>/<repo名>/rules?ref=refs%2Fheads%2Fhoge
remote:
remote: - Branch name must match a given regex pattern: EPT-[0-9X]*\/.*
remote:
To http://github.com/<org名>/<repo名>.git
 ! [remote rejected] hoge -> hoge (push declined due to repository rule violations)
error: failed to push some refs to 'http://github.com/<org名>/<repo名>.git'
error: GH013: Repository rule violations found for refs/heads/hoge.
Review all repository rules at http://github.com/<org名>/<repo名>/rules?ref=refs%2Fheads%2Fhoge
おお〜ちゃんとできたね。
ブランチ名の制限。
Org横断のルールなので他のリポジトリにすぐ適用できるのが良い