Closed26

GitHubのPull request merge queueを試す

Futa HirakobaFuta Hirakoba

これ

Pull request merge queue (public beta) | GitHub Changelog
https://github.blog/changelog/2023-02-08-pull-request-merge-queue-public-beta/

Futa HirakobaFuta Hirakoba

マージキューの機能はOrganizationのパブリックリポジトリまたはGHECのプライベートリポジトリで使えるらしい。個人じゃダメなのか〜

Pull request merge queues are available in any public repository owned by an organization, or in private repositories owned by organizations using GitHub Enterprise Cloud. For more information, see "GitHub's products."
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/merging-a-pull-request-with-a-merge-queue

Futa HirakobaFuta Hirakoba

大まかな流れ

  1. merge_groupトリガーで動作するワークフローを用意する
    • pull_requestあるいはpushトリガーとの併用を推奨[1]
  2. ターゲットブランチにbranch protection rulesを設定する
    1. Protect matching branches -> Require merge queueを有効化
      • パラメータは都度調整する
    2. Protect matching branches -> Require status checks to pass before mergingを有効化
      • Status checks that are required.にPRが溜まったキューで必ずパスしたいstatus checksを設定する(1. で用意したやつ)[2]
  3. Require merge queueを有効化したブランチに対するプルリクエストにMerge when readyというボタンが現れ、キューに貯められるようになる
    • Merge when readyを押すとstatus checksが通ると自動でキューに入る状態になる(auto mergeと同じ)
    • Require status checks to pass before mergingで有効にしたstatus checksを突破しないといけない
    • そのため、merge_group以外にpull_requestあるいはpushが必要となる
  4. マージキューにPRが増えると、merge_groupトリガーで動作するワークフローが発火する。一つのブランチにマージされたPR群に対してワークフローが実行される
    • Require status checks to pass before mergingで有効にしたstatus checksを突破するとターゲットブランチにマージされる

  • GitHub Actions以外のCIというかstatus checksでも使えるけど、その場合はブランチ名に条件があるらしい(参考)。まだ試してない。
脚注
  1. なぜなら、branch protection rulesのStatus checks that are required.を掛けたブランチに対して、必須とされるstatus checksは「PRをキューに入れる際(push, pull_requestで発火)」と「キューをターゲットブランチにマージする際(merge_groupで発火)」のパスする必要があるから ↩︎

  2. ここで一覧に目的のワークフローが出ないといけないが、条件はよくわかってない(一回どこかしらで実行されないといけない?) ↩︎

Futa HirakobaFuta Hirakoba

プルリクでMerge when readyってボタンが出るらしいが、GHESのリポジトリで見てもそんなものはない。

Repository administrators can require a merge queue by enabling the branch protection setting "Require merge queue" in the protection rules for the base branch. For more information, see "Managing a branch protection rule."
https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue#managing-a-merge-queue

branch protectionでマージキューを設定しないとダメかも。

Futa HirakobaFuta Hirakoba

required-merge-queueというブランチを対象に保護ルールを作ってみるよ


Protect matching branches にいた

設定あったね〜

  • Merges to matching branches must be performed via a merge queue. | 一致するブランチへのマージは、マージキューを経由して行わなければなりません。
  • Merge method
    • Method to use when merging changes from queued pull requests. | キューに入れられたプルリクエストから変更をマージする際に使用するメソッド。
      • Merge, Squash, Rebase から選べる
  • Build concurrency
    • Limit the number of queued pull requests building at the same time. | キューに入れられたプルリクエストを同時に構築する数を制限することができます。
    • Maximum pull requests to build: X| ビルドするための最大プルリクエスト数。
      • デフォルト値はX5
  • Merge limits
    • Limit the number of pull requests merged into the protected branch in a single merge operation. | 一度のマージ操作でprotectedブランチにマージされるプルリクエストの数を制限します。
      • Minimum pull requests to merge: X or after Y minites | マージするプルリクエストの最小値。XまたはY分後
        • デフォルト値はX1Y5
      • Maximum pull requests to merge: Z | マージするプルリクエストの最大数。
        • デフォルト値はZ5
      • Only merge non-failing pull requests | 失敗していないプルリクエストのみをマージする
        • デフォルト true
  • Status check timeout | ステータスチェックのタイムアウト
    • Time (in minutes) a required status check must report a conclusion within to not be considered failed. | ステータスチェックが失敗したとみなされないために必要な時間(分単位)。
      • Consider check failed after: X minutes | チェックに失敗したと考えてください。X` 分
        • デフォルトはX60
Futa HirakobaFuta Hirakoba

とりあえずデフォルトのままチェック入れてみる。

required-merge-queueブランチに対する適当なプルリクを作ったよ。


Merge when readyボタンが生えた


Confirm merge when readyで確認される

速攻でマージされた笑


merge queueのページ

履歴はないっぽい

速攻すぎてアレなのでちょっと設定を見直そう

Futa HirakobaFuta Hirakoba

Minimum pull requests to merge1に設定されているせいかもな〜
にしても瞬間でマージされるとは思わなかった。
相当動きの速いリポジトリが想定されてそう。

ステータスチェックが終わってたのも関係してそう。

とりあえずMinimum pull requests to merge 3 or 5 minutesに設定してみる。

別のプルリクエストを作成

3個溜まったら自動でマージされた

Futa HirakobaFuta Hirakoba

おそらく5分以上経ったら、maxにならなくてもマージされる。
次はキューに溜まった時のCIを設定したい

Futa HirakobaFuta Hirakoba

GitHub Actionsでキューに溜まったものをまとめてテストする

Futa HirakobaFuta Hirakoba

とりあえず作った。

.github/workflows/required-merge-queue.yaml
# testing required workflow
# https://github.blog/changelog/2023-01-10-github-actions-support-for-organization-wide-required-workflows-public-beta/
on:
  merge_group:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: ls
      - run: sleep 60

Ready when mergeしたけど、走らなかった。
先にベースブランチに存在する必要がありそう。

Minimum pull requests to merge 3 or 5 minutesに設定してるので5分まつか

Futa HirakobaFuta Hirakoba

プルリクを3つ用意

  • merge queueの実験だよ 5 by korosuke613 · Pull Request #12
  • merge queueの実験だよ 6 by korosuke613 · Pull Request #12
  • merge queueの実験だよ 7 by korosuke613 · Pull Request #12

まずは5, 6をMerge when readyする

Futa HirakobaFuta Hirakoba

2個追加した時点ではまだ走らない。

3個目いってみるか

...

あれーマージされてしまった。
CIは走らなかった

Futa HirakobaFuta Hirakoba

簡単にするために、Minimum pull requests to merge: 2にする
また、pull_requestイベントで動くワークフローをrequiredにした。

Futa HirakobaFuta Hirakoba

merge_group動いた。
キューにあるプルリクaで追加したaaaaaとプルリクbで追加したbbbbというファイルがちゃんとある。

よくわからんけど直ったっぽい

Futa HirakobaFuta Hirakoba

ただ、ずっとぐるぐるしている。

おそらくこれのせい

また、pull_requestイベントで動くワークフローをrequiredにした。
https://zenn.dev/link/comments/77a69c5cb7b912

pull_requestはトリガーされないからか。

merge queue 内で GitHub Action を動かすには Require status checks to pass before merging で動かしたい job を指定しておく必要がある。
これを指定しておかないと、merge queue に PR の変更が詰められても、ステータスチェックを待たずにベースブランチにマージされてしまう。
さらに、ここに指定する job の workflow は、先述の merge queue 追加時のイベントがないと、merge queue 追加時に job がトリガーされない。そのため、ステータスチェックが終わらずベースブランチにマージできないという現象が発生する。
https://medium.com/@ronnnnn_jp/github-の-merge-queue-を試してみて分かったこと-5c5b94cf477b

有識者のサイトにも書いてあった。
マージキューにおいてrequiredにするのはmerge_groupのジョブだけがいいっぽい。

Futa HirakobaFuta Hirakoba

requiredをmerge_groupのジョブのみに変更。
1分くらい経ったらマージされた!

Futa HirakobaFuta Hirakoba

再度実験。

あーrequiredをmerge_groupのみにすると、プルリクエストをMerge when readyにするときにジョブが走らないのにrequiredとなってしまう。

結局、merge_group単体で使うのは不便で、pushpull_requestと併用せざるを得ない感じか。

Futa HirakobaFuta Hirakoba

まとめた。

.github/workflows/required-test.yaml
# testing required workflow
# https://github.blog/changelog/2023-01-10-github-actions-support-for-organization-wide-required-workflows-public-beta/
on:
  merge_group:
  pull_request:

jobs:
  required-test-merge-group:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: ls
      - run: sleep 60
Futa HirakobaFuta Hirakoba

merge_groupに関しては、マージキューにキューが入るたびにイベントが発火するらしいらしい。
準備(キューに入ってるPRの最小を超える or 待ち時間を超える)ができてからイベントが発火するわけではないのか

Futa HirakobaFuta Hirakoba

キューに溜まったプルリクを選んで強制的にマージすることもできるっぽい

Futa HirakobaFuta Hirakoba

Triggering merge group checks with other CI providers

With other CI providers, you may need to update your CI configuration to run when a branch that begins with the special prefix gh-readonly-queue/{base_branch} is created.

他のCIで扱うこともできるが、その場合はブランチ名がgh-readonly-queue/{base_branch}でないといけないらしい。

https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue#triggering-merge-group-checks-with-other-ci-providers

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