課題認識

以前、以下の記事で Dependabot について調査しました。

その際、Dependabot によって作成された PR の自動マージを適切に運用できるよう、(ビルドやテストが失敗した場合に自動マージされないよう)Require status checks to pass を有効化しました。

このオプションの追加設定として Do not require status checks on creation というものがありました。このオプションはブランチ(や PR)が作られた時点では、ステータスチェックを必須にしないというもので、push 後にしか CI が動かないケースなど、ステータスチェックの制限によってPRがマージができないことを防ぐためのオプションだと理解しました。

説明を読んでもイマイチ理解できなかったので、改めて実機検証を通じて理解したいと思いました。

改めて説明を読む

当該オプションの説明には以下のように記載されています。

Allow repositories and branches to be created if a check would otherwise prohibit it.

(訳)ステータスチェックによって禁止されている場合でも、リポジトリとブランチの作成を許可します。

わかりませんので、GitHub のマニュアルを確認してみます。

“Do not require status checks on creation” について教えてください

と Copilot に聞いてみました。(右上の虫眼鏡マークから聞くことができます)

「Do not require status checks on creation」は、ルールセット内の必須ステータスチェック設定にあるオプション do_not_enforce_on_create を指します。意味と効果は次のとおりです。

  • 意味:新しくリポジトリやブランチを作成するとき、その作成操作に対して必須ステータスチェックの合格を要求しない(作成をブロックしない)設定です。
  • 効果:このオプションを有効にすると、通常なら必須チェックがないと作成できないようなブランチやリポジトリでも作成が可能になります。ただし、作成後にブランチに対してマージや更新を行う際は、ルールセットの必須ステータスチェックが通常どおり適用されます。
  • 利用ケース:既存のテンプレートや自動化で多数のリポジトリ/ブランチを作る必要があるが、作成時にCIなどのチェックがまだ整っていない場合などに便利です。

設定方法(概要):

  • ルールセットの必須ステータスチェックルールのパラメーターに do_not_enforce_on_create: true を含めます。これは REST API でルールセットを作成・更新する際のパラメーターとして利用できます。
  • GUIでの該当オプションについては、組織のルールセット作成画面で「Require status checks to pass before merging(必須ステータスチェック)」関連のオプションを確認してください。ルールを編集できるのはリポジトリ管理者または「edit repository rules」権限を持つカスタムロールです。

関連ドキュメント(詳細・APIパラメーター):

便利ですね。特定の機能に関する問題について、かなり効率的にマニュアル調査できるようになりました。

この回答の中に、

既存のテンプレートや自動化で多数のリポジトリ/ブランチを作る必要があるが、作成時にCIなどのチェックがまだ整っていない場合などに便利です。

という、ユースケースに関する記述がありました。

ブランチ作成を原則制限している(PR等によってきちんとチェックが通った場合に限りブランチを作成できる、など)が、自動化運用などにより、制限されたブランチでも自動作成できないと困る場合の回避策としてこのオプションがあるのかなと想像しました。

実際に試してみる

まずは適当にテスト用のリポジトリを作ります。

対象のリポジトリのページから、 Settings > Rules > Rulesets > New ruleset から新規のルールを作成します。 以下の Require status checks to pass にチェックをつけましょう。

ここで気がついたのですが、こちらのオプションを有効化するには、何かしらの Status Check を選択しなければなりません。GitHub Actions を Status Check として選択するために、mainブランチ(デフォルトブランチ)にステータスチェックようの CI を先に仕込んでおきましょう。

name: status-check-on-push
on:
  push:

jobs:
  job:
    runs-on: ubuntu-latest
    steps:
      - run: exit 1

今回は push によるブランチ作成がブロックされるかどうかを確認していきますので、push 時に失敗する CI として仕込みました。

ブランチルール設定の注意点として、以下のように All branches (もしくは今回作成するブランチパターン)を追加しておかないと、ルールが適用されないので注意しましょう。

ブランチを作成して、適当にコミットして push してみます。

git checkout -b fix/status-check-on-push-2
touch hogehoge
git add hogehoge
git commit -m 'status-check'
git push origin fix/status-check-on-push-2

push すると、、、

remote:
remote: - Required status check "statuscheck" is expected.
remote:
To https://github.com/a2-ito/do_not_enforce_on_create.git
 ! [remote rejected] fix/status-check-on-push-2 -> fix/status-check-on-push-2 (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/a2-ito/do_not_enforce_on_create.git'

push によるブランチ作成がでできませんでした。

Do not require status checks on creation にチェックを入れて再度 push してみます。

remote:
remote: Create a pull request for 'fix/status-check-on-push-2' on GitHub by visiting:
remote:      https://github.com/a2-ito/do_not_enforce_on_create/pull/new/fix/status-check-on-push-2
remote:
To https://github.com/a2-ito/do_not_enforce_on_create.git
 * [new branch]      fix/status-check-on-push-2 -> fix/status-check-on-push-2

push(ブランチ作成)ができました!

ちょっと気になったのが、on.push 時に実行される CI が正常終了したら push できるのか、という点です。やってみましょう。 正常終了する CI を用意します。

name: status-check-on-push
on:
  push:

jobs:
  job:
    runs-on: ubuntu-latest
    steps:
      - run: exit 0

早速新しいブランチを作成して push してみます。先程チェックした Do not require status checks on creation をチェック解除するのを忘れずに。

remote:
remote: - Required status check "statuscheck" is expected.
remote:
To https://github.com/a2-ito/do_not_enforce_on_create.git
 ! [remote rejected] fix/status-check-on-push-3 -> fix/status-check-on-push-3 (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/a2-ito/do_not_enforce_on_create.git'

だめでした。。。on.push だろうがなんだろうが、今回のオプションには関係なさそうですね。

まとめ

“Do not require status checks on creation” オプションは、ブランチ作成時に必須ステータスチェックを適用しない設定であることが実機検証で確認できました。

現在の私の業務では使う機会がなさそうですが、リポジトリやブランチ作成に対して強いガバナンスが必要な組織やプロジェクトにおいて、一定の柔軟性を持たせる有効なオプションなのかなと理解しました。