Files
LibreMail/.mergify.yml
T
JMR-dev 0c8a9e688f fix(ci): add queue_conditions identical to merge_conditions for in-place checks
The prior fix matched merge_conditions to auto_merge_conditions, but Mergify's
ruleset-compatibility check kept flagging "Configuration not compatible with
required_status_checks ruleset rule". The actual in-place-checks requirement is
that queue_conditions == merge_conditions, and this config had no
queue_conditions block at all, which Mergify reads as a two-step-CI mismatch.

Add a queue_conditions block to queue_rules.default identical (same conditions,
same order) to merge_conditions:
  - base = main
  - -draft
  - -conflict
  - label != broken
  - check-success = CI passed

Mergify runs three condition sets sequentially: auto_merge_conditions triggers
queueing, queue_conditions validates queue entry, merge_conditions validates the
merge. All three are now identical. With batch_size 1 and max_parallel_checks 1,
this makes Mergify validate PRs in place on the real branch, keeping the strict
require-up-to-date ruleset enabled (hard invariant). No other settings changed.
2026-07-07 16:17:10 -05:00

212 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPDX-License-Identifier: GPL-3.0-or-later
#
# ============================================================================
# Mergify configuration — PHASE 1: serial merge queue (issue #409).
#
# 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 on 2026-07-07 (file-format, queue
# rules, priority, merge-queue lifecycle/setup/batches, and the
# merge-protections auto-merge pages) — the config format evolves, so this is
# not from memory.
# 2026-07-07 CHANGE: auto-queueing migrated OFF the `pull_request_rules`
# queue-action path (which no longer auto-queues — a green matching PR just
# reported "Merge queue is ready — use `@Mergifyio queue`" and sat there) ONTO
# `merge_protections_settings.auto_merge_conditions` (see that block below).
# The old `autoqueue`/queue-action auto path is DEPRECATED and "will stop
# working on 2026-07-16" (docs.mergify.com/merge-queue/rules). This changes only
# the TRIGGER; the queue's merge semantics (below) are untouched.
# ============================================================================
#
# WHAT THIS DOES
# A SERIAL merge queue that ends the manual serial-bump grind and supersedes the
# hand-rolled "poor-man's merge queue" (autoupdate.yml + ci-trigger.yml +
# traffic-control.yml — all already `disabled_manually`). Mergify updates each
# queued PR onto the latest `main`, re-runs CI, and merges it with a MERGE COMMIT
# when the single required gate — the "CI passed" check — is green. One PR at a
# time, in P0–P9 priority order.
#
# HARD INVARIANTS (do NOT relax without the trilemma decision recorded in the spec):
# * require-up-to-date STAYS ON. This is Phase 1 = batch_size 1 + merge_method:
# merge — the ONLY trilemma combination that keeps GitHub's "Require branches to
# be up to date before merging" LITERALLY enabled AND preserves the merge-commit
# policy. Mergify honours it by updating each PR onto the latest `main` and
# re-running CI before merging ("Updates PRs against the latest main before
# merging" — docs.mergify.com/merge-queue/setup). NO batching: batching would
# require turning that checkbox OFF (docs.mergify.com/merge-queue/batches) and is
# the blocked Phase 2 / issue #410 — explicitly OUT OF SCOPE here.
# * The single required status check stays "CI passed" — the exact `name:` of the
# `ci-passed` job in .github/workflows/ci.yml. NOT "ci-passed". A wrong name means
# PRs queue but never merge.
# * IN-PLACE CHECKS, not speculative draft-PR checks. GitHub's strict
# `required_status_checks` ruleset (require-branches-up-to-date) rejects
# speculative checks outright — Mergify surfaced this as a "Configuration not
# compatible with `required_status_checks` ruleset rule" check on #422. The fix
# (per Mergify: docs.mergify.com/merge-queue/rules) is to make Mergify validate
# each PR IN PLACE, on the real PR branch, which requires ALL THREE of:
# (a) `merge_queue.max_parallel_checks: 1` (below),
# (b) every `queue_rules[].batch_size: 1` (below), and
# (c) `queue_rules.default.queue_conditions` IDENTICAL (same conditions, same
# order) to `queue_rules.default.merge_conditions` — i.e. no "two-step CI"
# where the conditions to ENTER the queue differ from the conditions to
# MERGE. Mergify runs three condition sets, sequentially:
# `merge_protections_settings.auto_merge_conditions` (TRIGGERS auto-queueing)
# → `queue_conditions` (validates a PR's queue ENTRY) → `merge_conditions`
# (validates the MERGE). Omitting `queue_conditions` — as this config first
# did — reads as a two-step-CI mismatch and re-trips the incompatibility
# check, so we keep all three lists identical. Do not let them drift apart.
# ---------------------------------------------------------------------------
# queue_rules — how a queued PR is validated and merged.
# ---------------------------------------------------------------------------
queue_rules:
- name: default
# Final merge gate. Merge ONLY when the single required context is green (the exact
# same check branch protection requires), the PR targets `main`, is not a draft, has
# no merge conflicts, and is not flagged `broken`. NOTE: branch protection requires 0
# approvals here (the active repository ruleset sets required_approving_review_count
# = 0), so there is deliberately NO `#approved-reviews-by` condition — adding one
# would wedge the solo-maintainer flow, where nobody can approve their own PR.
#
# IN-PLACE CHECKS: `queue_conditions` (what a PR must satisfy to ENTER/stay in the
# queue) MUST be IDENTICAL (same conditions, same order) to `merge_conditions` (what
# it must satisfy to MERGE) below. When those two lists match — plus batch_size 1 and
# max_parallel_checks 1 — Mergify validates each PR IN PLACE on the real PR branch
# instead of running speculative draft-PR checks, which is what GitHub's strict
# `required_status_checks` ruleset (require-branches-up-to-date) demands. Omitting
# `queue_conditions` (as this config originally did) is treated as a "two-step CI"
# mismatch and Mergify flags the ruleset as incompatible. Keep the three lists here —
# `queue_conditions`, `merge_conditions`, and
# `merge_protections_settings.auto_merge_conditions` — all identical; if any diverge,
# Mergify's ruleset-compatibility check fails again.
queue_conditions:
- base = main
- -draft
- -conflict
- label != broken
- check-success = CI passed
merge_conditions:
- base = main
- -draft
- -conflict
- label != broken
- check-success = CI passed
# SERIAL: exactly one PR per merge. No batching (Phase 2 / #410). One merge commit
# per PR, which is what lets require-up-to-date stay literally ON.
batch_size: 1
# 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:
# Validate ONE PR at a time — true serial, no speculative parallel checks. This is the
# strictest, unambiguously require-up-to-date-compatible setting: Mergify updates the
# REAL PR branch onto the latest `main`, runs CI on that branch, and merges on the real
# green "CI passed" — with no speculative temp-branch/real-branch check mismatch to
# reason about. It also caps the expensive, wedge-prone ~15-min E2E matrix at a single
# concurrent run. Raising this (speculative parallelism) is a throughput optimisation to
# weigh alongside the Phase 2 / #410 batching decision — not part of serial Phase 1.
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_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.
#
# This REPLACES the old `pull_request_rules` `queue` action. That action no longer
# auto-queues in current Mergify: a green, matching PR just reported "Merge queue is
# ready — use `@Mergifyio queue`" and sat there forever (never merged). Automatic
# queueing now lives in `auto_merge_conditions` under `merge_protections_settings`. The
# old `queue_rules[].autoqueue` field (and the queue-action auto path) is DEPRECATED and
# "will stop working on 2026-07-16. Use `auto_merge_conditions` in
# `merge_protections_settings` instead" (docs.mergify.com/merge-queue/rules).
#
# `auto_merge_conditions` accepts `true` (auto-queue every mergeable PR) or, as here,
# "a list of conditions to restrict the audience" (docs.mergify.com/configuration/
# file-format). We give the SAME set the old queue action used, so EXACTLY the same PRs
# auto-queue: green on "CI passed", targeting `main`, not a draft, no conflicts, not
# `broken`.
#
# WHY THIS PRESERVES require-up-to-date: this changes only the TRIGGER (manual →
# automatic). It does NOT touch how the queue validates or merges — batch_size 1,
# merge_method merge, and max_parallel_checks 1 above are unchanged — and those are the
# settings that interact with require-up-to-date (only BATCHING, batch_size > 1, forces
# that checkbox OFF; see the invariants header + docs.mergify.com/merge-queue/batches).
# When a merge queue is configured, a matched PR is auto-QUEUED, not merged directly:
# "Every PR is auto-queued. The merge queue then handles routing and merging"
# (docs.mergify.com/merge-protections/auto-merge) — so it still goes through the serial
# queue, gets updated onto the latest `main`, re-runs CI, and merges on the real green
# "CI passed". Mergify also auto-reads GitHub branch protection (the required "CI passed"
# check + require-up-to-date) and injects it as a merge condition, so the GitHub gate is
# enforced on top of queue_rules.merge_conditions.
#
# This list MUST stay IDENTICAL (same conditions, same order) to
# `queue_rules.default.queue_conditions` and `.merge_conditions` above — see the note
# there and the IN-PLACE CHECKS hard invariant at the top of this file.
# ---------------------------------------------------------------------------
merge_protections_settings:
auto_merge_conditions:
- base = main
- -draft
- -conflict
- label != broken
- check-success = CI passed