From 17018745d0772bb2a6e2fe02273681f2fafe65da Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Tue, 28 Apr 2026 13:15:13 -0700 Subject: [PATCH] fix(ci): auto-promote gate-check uses workflow file paths, not names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Observed 2026-04-28: auto-promote ran for staging head 96955f7b with all gates actually green (verified via /commits//check-runs API) yet `check-all-gates-green` reported `CodeQL → missing/none` and aborted. Same SHA was promotable; auto-promote couldn't see it. Cause: `gh run list --workflow="CodeQL"` matched two workflows in this repo: - codeql.yml (explicit, scans both staging and main) - codeql (GitHub UI-configured Code-quality default setup, internal, scans default branch only) gh CLI rejects ambiguous `--workflow=` lookups and returns no result → the gate fell through to `missing/none` and ALL_GREEN was set false. Every staging push since both names existed has been silently dead-locked. Fix: switch GATES from display-name strings to workflow file paths. File paths are the unique identifier for a workflow file in .github/workflows/; display names are decoration and can collide. The same `gh run list --workflow=` query that fails on "CodeQL" succeeds on "codeql.yml" because the file path resolves unambiguously. No behavior change for the other three gates (CI, E2E Canvas, E2E API Smoke) since their names didn't collide — they keep working, they just identify by ci.yml / e2e-staging-canvas.yml / e2e-api.yml now. The log line shape changes from `CI → completed/success` to `ci.yml → completed/success` which is fine for ops grep. When adding/removing a gate going forward: file paths only. Keep branch-protection required-checks (check-run display names) in sync as a separate manual step. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/auto-promote-staging.yml | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/auto-promote-staging.yml b/.github/workflows/auto-promote-staging.yml index c3427787..118d0c83 100644 --- a/.github/workflows/auto-promote-staging.yml +++ b/.github/workflows/auto-promote-staging.yml @@ -61,13 +61,30 @@ jobs: run: | set -euo pipefail - # Required gate workflow names. Must match the `name:` field - # in the respective .github/workflows/*.yml files. + # Required gate workflow files. Use file paths (relative to + # .github/workflows/) rather than display names because: + # + # 1. `gh run list --workflow=` is ambiguous when two + # workflows have the same `name:` — observed 2026-04-28 + # with "CodeQL" matching both `codeql.yml` (explicit) and + # GitHub's UI-configured Code-quality default setup + # (internal "codeql"). gh CLI returns "could not resolve + # to a unique workflow" → empty result → gate evaluated + # as missing/none → auto-promote dead-locked despite all + # checks actually passing. + # + # 2. File paths are the unique identifier for workflows; + # `name:` is just a display string and can collide. + # + # When adding/removing a gate, update this list AND the + # branch-protection required-checks list (which uses check-run + # display names, not workflow names; the two are decoupled and + # should be kept in sync manually). GATES=( - "CI" - "E2E Staging Canvas (Playwright)" - "E2E API Smoke Test" - "CodeQL" + "ci.yml" + "e2e-staging-canvas.yml" + "e2e-api.yml" + "codeql.yml" ) echo "head_sha=${HEAD_SHA}" >> "$GITHUB_OUTPUT"