Closed23

GitHub の Repository Rules を試してみる

Futa HirakobaFuta Hirakoba

Changelog を読む

もちろん DeepL Pro 先生が活躍。

Futa HirakobaFuta Hirakoba

前文

  • リポジトリルールはブランチ保護の進化系
  • 大規模なリポジトリでより安全でコンプラに準拠したリポジトリにすることを支援
  • ルールによってリポジトリ内のブランチやタグの保護を簡単に定義
  • GHECの顧客ならOrganization全体でそれを強制可能
  • リポジトリを読める全ての人がどのようなルールがあるのかを知ることも容易
Futa HirakobaFuta Hirakoba

ルールの作成

  • ルールの中核をなすのはルールセットを定義する機能
  • ルールセットとは、一緒に実施されるルールの集合体
  • 例:あるブランチへのコミットは署名付きで、そのコミットには2人のレビュアーがいることを要求
  • ルールセットはタグに適用でき、リリースにルールを適用することができる
  • ルールセットページはリポジトリの全てのルールを表示・管理するための中心
  • 新しいルールセットの追加や既存のルールセットの編集が可能
  • ルールセットにはenforcement statusがある
    • activeはコミットをマージするためにパスする必要がある
    • disabledはルールセットが強制されない。マージを妨げることはない。管理者はルールを強制する前にルールを作成できる
  • ルールセットでブランチやタグを対象とすることは容易で、便利な選択肢がある
    • デフォルトブランチ
    • 全てのブランチ
    • fnmatchパターンにマッチするブランチやタグ
  • ルールセットに複数のパターンを追加して異なるブランチやタグの命名スタイルに適用もできる
Futa HirakobaFuta Hirakoba

ルールを表示する

  • リポジトリにアクセスできる人なら誰でもルールと意味を見ることができる
  • ルールセットの概要はブランチページで盾のアイコンをクリックすると表示される
  • プルリクエストやルールがプッシュをブロックした時の Git CLI の出力からリンクされている
  • ブランチやタグでルールをフィルタリングして次のプッシュでルールがどのように実行されるかを理解できる
Futa HirakobaFuta Hirakoba

korosuke613/playground で試してみる

Futa HirakobaFuta Hirakoba

  • General
    • Name
      • ルールセット名を表す
    • Enforcement status
      • 有効(Active)か無効(Disabled)か選ぶ
      • デフォルト無効
    • Bypass mode
      • ルールセットを無視できる人を指定する
      • デフォルトでNot permitted。誰も無視できない
      • もしくはRepository bypass permitted。次の人物がバイパスできる
        • Organization Administrators
        • Repository Administrators
        • リポジトリバイパス権限を持つユーザ
  • Bypass list
    • チームまたはアプリをバイパスリストに追加することでルールセットを無視できる
    • 人(user)は選べなさそう
  • Target branches
    • ルールセットで保護するブランチを指定する
    • ブランチは複数個追加できる
    • ブランチの追加の選択肢は 4 つ
      • Include default branch: デフォルトブランチをルールの対象とする
      • Include all branches: 全てのブランチをルールの対象とする
      • Include by pattern: fnmatch に一致するブランチをルールの対象とする。releases/**/*みたいな
      • Exclude by pattern: fnmatch に一致するブランチをルールの対象から外す。
  • 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 を禁止
Futa HirakobaFuta Hirakoba

conventional commitの強制ができるmetadata restrictionsは個人では使えないらしい。

Futa HirakobaFuta Hirakoba

試しに、try-rulesets/**/*にマッチするブランチに対するルールセットを作った。
branch protections は Restrict creations、Restrict deletions、Block force pushes のみ。

Futa HirakobaFuta Hirakoba

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

理由もちゃんと出てるね。

Futa HirakobaFuta Hirakoba

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'.

ちゃんと送れた。

Futa HirakobaFuta Hirakoba

個人だとそこまでできることはブランチ保護と変わらないかな。
次はGHECの方でやってみよう。

Futa HirakobaFuta Hirakoba

GHEC (会社のリポジトリ) で試してみる

Futa HirakobaFuta Hirakoba

まずはルール作成。
基本は個人の設定と一緒。
ただ、いくつか違う点がある。

  • General
    • Enforcement status
      • DisabledActive に加えて Evaluate が増えている
      • Evaluate にするとルールは強制されないが、Insights ページからルールセットがアクティブであった場合に合格または失敗を確認できる(参考
  • Metadata restrictions
    • 個人向けにはなかった項目
    • コミットのメタデータについての制限をかけられる
    • 次の選択肢を掛け合わせる
      • Applies To: 対象
        • Commit message
        • Author email
        • Committer email
        • Branch name
      • Requirement: 要件
        • パターンと前方一致する
        • パターンと後方一致する
        • パターンが含まれる
        • 正規表現とマッチする
        • パターンと前方一致しない
        • パターンと後方一致しない
        • パターンが含まれない
        • 正規表現とマッチしない
      • Matching pattern: パターンを記述
      • Description: 概要を記述
Futa HirakobaFuta Hirakoba

作った。

評価モードで、コミット署名必須&コミットメッセージが^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]*: .*
Futa HirakobaFuta Hirakoba

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 してるねぇ。

詳細も見れる。

Futa HirakobaFuta Hirakoba

今度はルールに反するコミットをpushしてみる。


コミットメッセージのルールを無視した。

ちゃんと Fail になった。

理由もコミットメッセージがダメってでる。


署名が必須のルールを無視した。
コミット時に--no-gpg-signをつけて署名を外す。

ちゃんと Fail になった。

理由も署名がないってでる。

Futa HirakobaFuta Hirakoba

GHEC で Organization 単位のルールセットを試してみる

Futa HirakobaFuta Hirakoba

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にするとバイパスできる人のみ変更できるようになる
Futa HirakobaFuta Hirakoba

今回はブランチ名を強制するルールを作ってみる

  • 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]*\/.*

EPT-2023/happy-new-year みたいなブランチ名しか受け付けない設定。


ちゃんとどのリポジトリが対象かも出てきていいね

Futa HirakobaFuta Hirakoba

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横断のルールなので他のリポジトリにすぐ適用できるのが良い

このスクラップは2023/06/19にクローズされました