From 55196b6623658d195b516c6aa7df411c76f8b188 Mon Sep 17 00:00:00 2001 From: Yuriy Andamasov Date: Tue, 2 Jun 2026 02:58:28 +0300 Subject: [PATCH] T8943: fix(mirror): anchor force_workspace parser to real Mergify abort wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The force_workspace backport parser anchored its SHA + branch regexes to assumed Mergify wording ("(?:commit|Backport of) <40hex>", bare "to branch ") that never matched real output. Verified against the in-prod abort VyOS-Networks/vyos-1x#2116 (2026-05-15): Mergify writes "Cherry-pick of <40hex> has failed:" and "Backport to branch `` failed" (branch in backticks). Both shipped regexes returned 0 matches on the real body -> parse step exit 1 -> force_workspace would silently abort. The smoke fixtures encoded the same fictional wording, so the smoke test + all prior review gates passed against invented strings (test mirrored the bug). Fix: - SHA_RE -> r"\b(?:[Cc]herry-pick of|Backport of)\s+(?:commit\s+)?([0-9a-f]{40})\b" - BRANCH_RE-> r"to branch\s+`?(sagitta|circinus)`?\b" (backtick-tolerant) - smoke fixtures rewritten to Mergify's REAL wording (verbatim from #2116), + a multi-branch fail-closed negative (one comment naming two branches -> reject; force_workspace acts on one branch per invocation). - parser regexes kept byte-identical (lockstep) across reusable + smoke. Caught at the Rollout 4 canary pre-flight before the live synthetic test. 🤖 Generated by [robots](https://vyos.io) --- .../workflows/force-workspace-backport.yml | 17 ++++-- .../force-workspace-parser-smoke.yml | 54 +++++++++++++------ 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/.github/workflows/force-workspace-backport.yml b/.github/workflows/force-workspace-backport.yml index 803d8de..ff88488 100644 --- a/.github/workflows/force-workspace-backport.yml +++ b/.github/workflows/force-workspace-backport.yml @@ -74,10 +74,19 @@ jobs: BODY="$(cat /tmp/mergify_comment_body.txt)" python3 - <<'PYEOF' >> "$GITHUB_OUTPUT" import os, re, sys body = os.environ["BODY"] - BRANCH_RE = r"\b(?:to(?: branch)?|for branch)\s+(sagitta|circinus)\b" - # SHA anchored to Mergify's commit context ("cherry-pick of commit " / "Backport of ") - # so an unrelated bare 40-hex elsewhere (URL, prior-PR reference) is NOT picked up (F5/anchoring). - SHA_RE = r"\b(?:commit|Backport of)\s+([0-9a-f]{40})\b" + # Anchored to Mergify's REAL "No backport have been created" failure wording, captured verbatim + # from in-prod abort VyOS-Networks/vyos-1x#2116 (2026-05-15): + # #### ❌ No backport have been created + # * Backport to branch `circinus` failed due to conflicts + # Cherry-pick of 6df7ca2f61ce1aa8352e8dbb1fc6e9c5d6d42937 has failed: + # Branch name is wrapped in backticks; SHA is introduced by "Cherry-pick of <40hex>". + # (The earlier "(?:commit|Backport of)" / bare-"to branch" anchors never matched real output — + # caught at the Rollout 4 canary pre-flight; the smoke fixtures had mirrored the wrong wording.) + BRANCH_RE = r"to branch\s+`?(sagitta|circinus)`?\b" + # SHA anchored to the failed-cherry-pick sentence so an unrelated bare 40-hex elsewhere + # (URL, prior-PR reference) is NOT picked up (F5/anchoring). "Backport of " kept as a + # robustness alternate; the short 9-hex "commit 6df7ca2f6" line is correctly ignored ({40}). + SHA_RE = r"\b(?:[Cc]herry-pick of|Backport of)\s+(?:commit\s+)?([0-9a-f]{40})\b" shas = sorted(set(re.findall(SHA_RE, body, re.IGNORECASE))) branches = sorted({m.lower() for m in re.findall(BRANCH_RE, body, re.IGNORECASE)}) if len(shas) != 1 or len(branches) != 1: diff --git a/.github/workflows/force-workspace-parser-smoke.yml b/.github/workflows/force-workspace-parser-smoke.yml index 3a6db7d..4a1b9d9 100644 --- a/.github/workflows/force-workspace-parser-smoke.yml +++ b/.github/workflows/force-workspace-parser-smoke.yml @@ -27,29 +27,53 @@ jobs: import re, sys # Fixtures: each is (body, expected_sha, expected_branch). expected_sha=None means the - # parser MUST REJECT (ambiguous or no anchored commit SHA) — negative cases. + # parser MUST REJECT (ambiguous, no anchored SHA, or multi-branch) — negative cases. + # + # POSITIVE fixtures use Mergify's REAL "No backport have been created" wording, captured + # verbatim from in-prod abort VyOS-Networks/vyos-1x#2116 (2026-05-15). The branch name is + # wrapped in backticks; the SHA is introduced by "Cherry-pick of <40hex> has failed:". + # If Mergify's failure-comment format ever drifts from this, THIS test goes red — which is + # the guard the prior (fictional-wording) fixtures failed to provide. FIXTURES = [ - # Positive: SHA in "cherry-pick of commit " context, branch in "to/for branch". - ("""The backport of pull request #42 to branch sagitta failed. + # Positive (real circinus abort, verbatim from #2116): + ("""#### ❌ No backport have been created - No backport have been created for branch sagitta. The cherry-pick of commit abc123def4567890abcdef1234567890abcdef12 failed:""", - "abc123def4567890abcdef1234567890abcdef12", "sagitta"), - # Positive: "Backport of to " context. - ("""Backport of abcdef1234567890abcdef1234567890abcdef12 to circinus failed: deleted by us.""", - "abcdef1234567890abcdef1234567890abcdef12", "circinus"), + * Backport to branch `circinus` failed due to conflicts + + Cherry-pick of 6df7ca2f61ce1aa8352e8dbb1fc6e9c5d6d42937 has failed: + You are currently cherry-picking commit 6df7ca2f6.""", + "6df7ca2f61ce1aa8352e8dbb1fc6e9c5d6d42937", "circinus"), + # Positive (real-wording sagitta variant): + ("""#### ❌ No backport have been created + + * Backport to branch `sagitta` failed due to conflicts + + Cherry-pick of abcdef1234567890abcdef1234567890abcdef12 has failed:""", + "abcdef1234567890abcdef1234567890abcdef12", "sagitta"), # NEGATIVE: failure branch present but the only 40-hex is an UNRELATED bare SHA in a URL - # (no commit/Backport-of anchor) → anchored SHA_RE finds 0 → must REJECT (not pair a stray SHA). - ("""No backport have been created for branch sagitta. + # (no Cherry-pick-of/Backport-of anchor) → anchored SHA_RE finds 0 → must REJECT. + ("""No backport have been created. + * Backport to branch `sagitta` failed due to conflicts See https://github.com/vyos/vyos-1x/commit/0000000000000000000000000000000000000000 for context.""", None, None), - # NEGATIVE: two distinct anchored commit SHAs → ambiguous → must REJECT. - ("""Backport of 1111111111111111111111111111111111111111 to circinus failed. - The cherry-pick of commit 2222222222222222222222222222222222222222 also failed.""", + # NEGATIVE: two distinct anchored SHAs → ambiguous → must REJECT. + ("""Cherry-pick of 1111111111111111111111111111111111111111 has failed. + Cherry-pick of 2222222222222222222222222222222222222222 has failed. + * Backport to branch `circinus` failed due to conflicts""", + None, None), + # NEGATIVE: one comment naming TWO branches (e.g. `@Mergifyio backport sagitta circinus` + # where both fail) → two distinct branches → fail-closed REJECT (force_workspace acts on + # one branch per invocation; multi-branch is left to manual fallback — documented gap). + ("""#### ❌ No backport have been created + * Backport to branch `sagitta` failed due to conflicts + Cherry-pick of 6df7ca2f61ce1aa8352e8dbb1fc6e9c5d6d42937 has failed: + * Backport to branch `circinus` failed due to conflicts""", None, None), ] - BRANCH_RE = r"\b(?:to(?: branch)?|for branch)\s+(sagitta|circinus)\b" - SHA_RE = r"\b(?:commit|Backport of)\s+([0-9a-f]{40})\b" + # Lockstep with force-workspace-backport.yml's parse step (keep byte-identical): + BRANCH_RE = r"to branch\s+`?(sagitta|circinus)`?\b" + SHA_RE = r"\b(?:[Cc]herry-pick of|Backport of)\s+(?:commit\s+)?([0-9a-f]{40})\b" # Lockstep with the reusable's parser: set-based with exactly-one-distinct assertion # (anchored/ambiguity-safe). Keep identical to force-workspace-backport.yml's parse step.