171 lines
8.0 KiB
YAML
171 lines
8.0 KiB
YAML
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
#
|
|
# ============================================================================
|
|
# Mergify configuration — PHASE 2: batched merge queue (issue #410).
|
|
#
|
|
# Spec: docs/ci/mergify-integration-spec.md + docs/ci/mergify.yml.proposed
|
|
# (issues #407 / #408).
|
|
# Schema: https://docs.mergify.com/configuration/file-format/
|
|
# Verified against the LIVE Mergify docs (file-format, queue rules, priority,
|
|
# merge-queue batches) on 2026-07-08 — the config format evolves, so this is
|
|
# not from memory.
|
|
#
|
|
# HISTORY
|
|
# Phase 1 (#409; landed #422, proven by #425/#426) ran a SERIAL queue — batch_size 1
|
|
# + max_parallel_checks 1 + queue_conditions == merge_conditions — which kept GitHub's
|
|
# "Require branches up to date before merging" checkbox LITERALLY on. It was proven
|
|
# end-to-end: mergify[bot] auto-merged #425/#426, and serialised #426 -> #427 by
|
|
# updating #427 onto the new `main` (incl. #426) and re-running CI before merging.
|
|
# Phase 2 (this file, #410) turns on BATCHING now that the queue is proven.
|
|
# ============================================================================
|
|
#
|
|
# WHAT THIS DOES
|
|
# A BATCHED merge queue. Mergify takes up to `batch_size` queued PRs, builds ONE
|
|
# speculative branch = (latest `main` + all the batched PRs), runs CI on that combined
|
|
# branch ONCE, and — if green — merges the whole batch (each as a MERGE COMMIT) in
|
|
# P0-P9 priority order. That is ~`batch_size`x the throughput of Phase-1 serial (one CI
|
|
# cycle merges many PRs, not one) while STILL testing every PR against the latest `main`
|
|
# (they all ride the same speculative batch branch).
|
|
#
|
|
# THE require-up-to-date SWAP (the one hard change from Phase 1 — do not misread it):
|
|
# * Batching is INCOMPATIBLE with GitHub's "Require branches to be up to date before
|
|
# merging" (docs.mergify.com/merge-queue/batches): a batch branch is by construction
|
|
# "ahead of" its member PRs, so that per-PR linear check cannot pass. It is therefore
|
|
# turned OFF in the `main` ruleset (18347032 -> `required_status_checks
|
|
# .strict_required_status_checks_policy` = false). The required "CI passed" CHECK
|
|
# itself STAYS required — only the "must be up to date" part is dropped.
|
|
# * The INVARIANT that option protected — never merge code untested against the latest
|
|
# `main` — is NOT lost; it MOVES to Mergify. The speculative batch branch IS
|
|
# latest-`main`-plus-the-batch, so a green batch check IS the against-latest-main
|
|
# test. This is the sanctioned swap (invariant preserved, enforcement relocated),
|
|
# authorised ONLY because Phase 1 proved the queue actually performs that update+re-CI.
|
|
# Do NOT drop require-up-to-date for any reason that does NOT relocate the invariant.
|
|
# * The single required status check stays "CI passed" — the exact `name:` of the
|
|
# `ci-passed` job in .github/workflows/ci.yml. NOT "ci-passed".
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# queue_rules — how a batch of queued PRs is validated and merged.
|
|
# ---------------------------------------------------------------------------
|
|
queue_rules:
|
|
- name: default
|
|
# Merge a batch ONLY when the combined batch branch is green on the single required
|
|
# context ("CI passed"), every member PR targets `main`, is not a draft, has no merge
|
|
# conflict, and is not flagged `broken`. NOTE: the ruleset requires 0 approvals
|
|
# (required_approving_review_count = 0), so there is deliberately NO `#approved-reviews-by`
|
|
# condition — it would wedge the solo-maintainer flow (nobody can approve their own PR).
|
|
#
|
|
# queue_conditions (queue ENTRY) are kept IDENTICAL — same conditions, same order — to
|
|
# merge_conditions (MERGE). Under Phase 1 this identity was REQUIRED for in-place-checks
|
|
# compatibility with the strict ruleset; with require-up-to-date now off, batching uses
|
|
# speculative batch checks and the identity is no longer mandatory — but it is kept so
|
|
# auto_merge_conditions / queue_conditions / merge_conditions remain one single source of
|
|
# truth (no reason for entry and merge gates to differ). Keep all three lists identical.
|
|
queue_conditions:
|
|
- base = main
|
|
- -draft
|
|
- -conflict
|
|
- label != broken
|
|
- check-success = CI passed
|
|
merge_conditions:
|
|
- base = main
|
|
- -draft
|
|
- -conflict
|
|
- label != broken
|
|
- check-success = CI passed
|
|
# BATCHING (Phase 2 / #410): validate up to 5 PRs together on ONE speculative branch, so
|
|
# a single ~15-min CI cycle can merge up to 5 PRs instead of 1. `batch_max_wait_time`
|
|
# bounds how long Mergify waits to fill a batch before starting CI on a partial one, so a
|
|
# lone PR is not left waiting for companions. Requires the require-up-to-date checkbox OFF
|
|
# (see the SWAP note in the header).
|
|
batch_size: 5
|
|
batch_max_wait_time: 5 min
|
|
# Merge commit — never squash / rebase / fast-forward (repo policy: merges use merge
|
|
# commits, never squash).
|
|
merge_method: merge
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# merge_queue — queue-wide options.
|
|
# ---------------------------------------------------------------------------
|
|
merge_queue:
|
|
# One batch validated at a time. `batch_size` (above) — not parallelism — is the Phase-2
|
|
# throughput lever: a single batch of up to 5 PRs merges per CI cycle, keeping the
|
|
# expensive/wedge-prone ~15-min E2E matrix to ONE concurrent run. Raising this would run
|
|
# multiple batches' CI concurrently (more runner load / cost) — a later tuning knob, not
|
|
# needed to get the batching win.
|
|
max_parallel_checks: 1
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# priority_rules — map the repo's P0-P9 labels onto queue priority.
|
|
# Higher number merges first (Mergify keywords: low=1000 / medium=2000 / high=3000;
|
|
# numeric range 1-10000). P0 is emergency-only and outranks everything. PRs with no P-label
|
|
# fall to Mergify's default `medium` (2000). Priority also orders merges within a batch.
|
|
# ---------------------------------------------------------------------------
|
|
priority_rules:
|
|
- name: p0-emergency
|
|
conditions:
|
|
- label = P0
|
|
priority: 10000
|
|
allow_checks_interruption: true
|
|
- name: p1
|
|
conditions:
|
|
- label = P1
|
|
priority: 9000
|
|
allow_checks_interruption: true
|
|
- name: p2
|
|
conditions:
|
|
- label = P2
|
|
priority: 8000
|
|
allow_checks_interruption: true
|
|
- name: p3
|
|
conditions:
|
|
- label = P3
|
|
priority: 7000
|
|
allow_checks_interruption: true
|
|
- name: p4
|
|
conditions:
|
|
- label = P4
|
|
priority: 6000
|
|
allow_checks_interruption: true
|
|
- name: p5
|
|
conditions:
|
|
- label = P5
|
|
priority: 5000
|
|
allow_checks_interruption: true
|
|
- name: p6
|
|
conditions:
|
|
- label = P6
|
|
priority: 4000
|
|
allow_checks_interruption: true
|
|
- name: p7
|
|
conditions:
|
|
- label = P7
|
|
priority: 3000
|
|
allow_checks_interruption: true
|
|
- name: p8
|
|
conditions:
|
|
- label = P8
|
|
priority: 2000
|
|
- name: p9
|
|
conditions:
|
|
- label = P9
|
|
priority: 1000
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# merge_protections_settings — WHICH PRs are AUTOMATICALLY added to the queue.
|
|
# (Unchanged from Phase 1 — this is the auto-queue TRIGGER, orthogonal to batching.)
|
|
#
|
|
# Automatic queueing lives in `auto_merge_conditions` (the old `pull_request_rules` queue
|
|
# action no longer auto-queues — deprecated 2026-07-16). Same audience as before: green on
|
|
# "CI passed", targeting `main`, not a draft, no conflicts, not `broken`. A matched PR is
|
|
# auto-QUEUED (not merged directly); the batched queue then routes + merges it.
|
|
#
|
|
# Kept IDENTICAL (same conditions, same order) to queue_conditions / merge_conditions above.
|
|
# ---------------------------------------------------------------------------
|
|
merge_protections_settings:
|
|
auto_merge_conditions:
|
|
- base = main
|
|
- -draft
|
|
- -conflict
|
|
- label != broken
|
|
- check-success = CI passed
|