はじめに
前回の記事では、GitHub Merge Queueを利用して「テストを通過した変更だけをブランチへ取り込む」仕組みについて紹介しました。
しかし、実際の現場では以下のような課題があります。
- 既に複数チームが同じリポジトリを利用している
- チームによって開発フローが異なる
- いきなり全チームへMerge Queueを強制することは難しい
- モノレポでは変更対象によって実行したいテストが異なる
今回は、モノレポ環境で一部チームからMerge Queueを導入する方法を紹介します。
1. モノレポでmainにMerge Queueを設定する問題
例えば以下のようなモノレポ構成を考えます。
repository
├── src
│ ├── BackendApp
│ ├── FrontendApp
│ └── Migrate
ここでBackendAppチームだけ品質ゲートを強化したいとします。
単純にmainへRulesetを設定すると、
main
Require pull request
Require merge queue
Require status checks
になります。
しかし、mainは全チームが利用しています。
例えば別チームが、
FrontendApp
|
v
mainへpush
という運用をしていた場合、Merge Queue必須になってしまいます。
つまり、一部チームだけ導入したい場合にはmainへ直接設定することはできません。
2. Merge Queue用のdevelopブランチを作成する
そこで、Merge Queueを利用するチーム用にdevelopブランチを作成します。
構成:
main
|
+----------------+
|
develop
|
BackendApp Team
役割を分離します。
main
- 既存チーム用
- 今まで通りの開発フローを維持
develop
- Merge Queue導入チーム用
- 品質ゲートを設定するブランチ
3. developブランチへRulesetを設定する
developに対してRulesetを設定します。
例:
develop
Require pull request
Require status checks
Require merge queue
これにより、
feature branch
|
v
Pull Request
|
v
develop Merge Queue
|
v
develop
という流れになります。
4. Merge Queueでは2つのタイミングでテストが必要
Merge Queueでは、テスト実行タイミングが2つあります。
Pull Request作成
|
| pull_request
v
テスト実行
|
v
Merge Queue追加
|
| merge_group
v
テスト実行
|
v
developへmerge
それぞれ役割が異なります。
pull_request
目的:
- 開発者へ早くフィードバックする
- Merge Queueへ追加可能な状態か確認する
merge_group
目的:
- 実際にマージされるコミット集合を検証する
- 最終的な品質保証を行う
5. Required Checkは分けない
ここがMerge Queueでハマりやすいポイントです。
以下のようにStatus Checkを分けたくなります。
Required checks
✅ pr-test / test
✅ merge-queue-test / test
しかし、この構成は問題があります。
PR作成時:
Pull Request
pr-test / test
|
success
merge-queue-test / test
|
Waiting
になります。
なぜなら、merge_groupイベントはMerge Queueへ追加された後にしか発生しないためです。
つまりPR時点では、
quality-gate / verify
というStatus Checkは存在しません。
6. 同じStatus Checkをイベントによって使い分ける
正しい設計は、1つのStatus Checkを利用します。
test
pull_request
|
+-- 軽量テスト
merge_group
|
+-- 本番前フルテスト
GitHub Actionsではイベント種別を判定し、処理を分岐します。
7. GitHub Actions Workflow例
.github/workflows/quality-gate.yml
name: quality-gate
on:
pull_request:
branches: [develop]
merge_group:
branches: [develop]
types: [checks_requested]
jobs:
detect:
runs-on: ubuntu-latest
outputs:
backendapp: ${{ steps.changes.outputs.backendapp }}
migrate: ${{ steps.changes.outputs.migrate }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed apps
id: changes
uses: dorny/paths-filter@v4
with:
filters: |
backendapp:
- 'src/BackendApp/**'
migrate:
- 'src/migrate/**'
verify:
needs: detect
runs-on: ubuntu-latest
steps:
# pull_requestの場合
- name: BackendApp PR Test
if: |
github.event_name == 'pull_request' &&
needs.detect.outputs.backendapp == 'true'
run: |
echo "Run BackendApp PR Test"
- name: Migrate PR Test
if: |
github.event_name == 'pull_request' &&
needs.detect.outputs.migrate == 'true'
run: |
echo "Run Migrate PR Test"
# merge_groupの場合
- name: BackendApp Merge Queue Test
if: |
github.event_name == 'merge_group' &&
needs.detect.outputs.backendapp == 'true'
run: |
echo "Run BackendApp Full Test"
- name: Migrate Merge Queue Test
if: |
github.event_name == 'merge_group' &&
needs.detect.outputs.migrate == 'true'
run: |
echo "Run Migrate Full Test"
# 対象変更なし
- name: Skip Test
if: |
needs.detect.outputs.backendapp != 'true' &&
needs.detect.outputs.migrate != 'true'
run: |
echo "No target application changed"
8. paths-filterで変更アプリだけテストする
モノレポでは、毎回すべてのアプリをテストすると実行時間が増加します。
そのため、変更されたフォルダーを検出して対象アプリだけテストします。
例えば、
src
├── BackendApp
├── FrontendApp
└── migrate
の場合、
BackendAppだけ変更:
src/BackendApp/*
なら、
BackendApp Test
だけ実行します。
migrateだけ変更:
src/migrate/*
なら、
Migrate Test
だけ実行します。
9. 最終的な開発フロー
BackendAppチーム:
feature/backend
|
v
Pull Request
|
v
test
(pull_request)
|
v
Merge Queue
|
v
test
(merge_group)
|
v
develop
他チーム:
feature/frontend
|
v
main
(既存フロー)
10. まとめ
モノレポ環境では、全チームへMerge Queueを一斉導入することは難しいケースがあります。
その場合は、
- Merge Queueを利用するチーム用のdevelopブランチを作成する
- Rulesetはdevelopへ設定する
- pull_requestとmerge_groupの両方で同じStatus Checkを発行する
- イベントによってテスト内容を変更する
- paths-filterで変更アプリのみテストする
という構成にすることで、既存チームの開発速度を維持しながら段階的に品質向上できます。
Merge Queueは「全員に強制する仕組み」ではなく、チームやアプリ単位で導入範囲をコントロールすることで、モノレポ環境でも効果的に利用できます。