diff options
| -rw-r--r-- | .mergify.yml | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/.mergify.yml b/.mergify.yml index 01b818e..74e9439 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -39,14 +39,22 @@ defaults: # accountability loop — they wrote the change, they know what the # backport should look like. # - # Operational caveat — the label DOES NOT block merge by itself. The - # 2026-05-12 incident below shipped because branch protection did not - # require a check that catches conflict markers. Repos consuming - # `extends: mergify` need either (a) a required CI status that fails - # on `<<<<<<<` in tracked files, or (b) a branch-protection ruleset - # that forbids merging while `backport-conflict` is present. Both - # belong to fleet-wide governance, tracked under T8850 (Cat 1 branch - # governance rulesets) rather than this central-config repo. + # Merge is blocked while the label is present — see the + # `merge_protections` block at the bottom of this file. Mergify + # documents that merge_protections are "safe to edit live; + # re-evaluations happen automatically", so a PR that gains the + # label after queueing will fail the merge check at the next + # evaluation. Active ejection of a queued PR vs. holding it + # indefinitely is not explicitly documented; manual fallback is + # `@Mergifyio dequeue` (allowed to Maintainers per + # commands_restrictions below). + # + # This does NOT replace branch protection. A determined operator can + # still bypass via the GitHub "Merge" button if branch protection + # doesn't require Mergify checks. The defense-in-depth piece (required + # CI status that fails on `<<<<<<<` in tracked files, or branch- + # protection ruleset on the label) is tracked under T8850 (Cat 1 + # branch governance rulesets). # # Incident history (2026-05-12): # vyos/vyos-documentation#1994 was backported via `@Mergifyio backport @@ -158,3 +166,36 @@ commands_restrictions: requeue: *allowed squash: *allowed update: *allowed + +merge_protections: + # Block merge while the backport-conflict label is set on a PR. The + # `backport` action above adds this label whenever a backport cherry-pick + # produces conflict markers; this rule ensures the conflicted PR cannot + # proceed to merge until a human removes the label (which they should + # only do after pushing a resolution commit that overwrites the markers). + # + # Why merge_protections and not a pull_request_rules `dequeue` action: + # Mergify exposes `dequeue` as a user-facing slash command and as a key + # under `commands_restrictions`, but NOT as a YAML action in + # pull_request_rules. `merge_protections` is the declarative equivalent — + # a PR with the label fails the success_conditions and is held back from + # merge; manual `@Mergifyio dequeue` remains available as the escape + # hatch (allowed to Maintainers per commands_restrictions above). + # + # Inheritance: per Mergify docs, merge_protections from `extends:` + # merges across parent and child, with same-named rules in the child + # overriding the parent. Consumer repos can disable this rule by + # defining a same-named rule locally with weaker conditions. + # + # Caveat: merge_protections only governs Mergify-driven merges. A + # determined operator can still click GitHub's merge button if branch + # protection doesn't require Mergify checks. Defense-in-depth (required + # CI status, branch-protection ruleset on the label) is tracked under + # T8850 Cat 1 branch governance. + - name: backport-conflict label must be absent to merge + description: > + Block merge while the backport-conflict label is present. The label + is auto-applied by the backport action on cherry-pick conflicts and + must be manually removed after the conflict is resolved in the PR. + success_conditions: + - label != backport-conflict |
