Files
open-design/e2e
92f219d20b feat(ci): auto-merge clean backports on green CI (+ Feishu ping on failure) (#4671)
* feat(ci): auto-merge clean backports on green CI + Feishu ping on failure

release/v* is PR-protected but has no merge queue and no required status check, so neither
GitHub auto-merge nor enqueuePullRequest applies. backport-automerge.yml reacts to ci.yml
completing for a backport-* branch:
- success + clean (non-draft) PR -> squash-merge with the App token (the push to release/*
  re-triggers notify-release-feishu / the nightly)
- failure -> Feishu ping for manual follow-up
- conflict (draft) -> left for a human; release-gate blocks the release until it lands

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ci): harden backport auto-merge — verify head identity + bind to CI SHA

Per review (PerishCode):
- Only auto-merge PRs authored by the release bot from the same repo (author ==
  open-design-release-bot[bot] && !isCrossRepository), so a stranger can't get a branch
  named backport-* auto-merged with the App token.
- Bind the merge to the SHA CI actually passed on: gate on head_oid == workflow_run.head_sha
  and pass --match-head-commit, so a commit pushed after CI went green is never merged
  untested (release/v* has no required status checks to catch it).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ci): restrict backport auto-merge to PR CI runs + gate the Feishu path too

Per review (PerishCode):
- Only run for workflow_run.event == 'pull_request' on a backport-* branch, so a push or
  manual dispatch can't reach the App-token / Feishu steps.
- Apply the same author == bot && !isCrossRepository gates to the Feishu failure step, so a
  fork / non-bot PR named backport-* can't spam the release group.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(ci): add topology coverage for the backport-automerge trusted workflow

Per review (PerishCode): packaged-smoke-workflow.test.ts registers backport-automerge.yml as a
ci workflow_run consumer and asserts its trust gates — workflow_run.event == pull_request, the
App-token mint, author == bot && !isCrossRepository && non-draft && release/v* base, the
head_oid == workflow_run.head_sha + --match-head-commit binding, and the same identity gates on
the Feishu failure path — so the security posture is covered by tests, not just YAML review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ci): resolve the backport PR by the CI run's SHA, not just the branch name

Per review (PerishCode): bind the resolved PR to the completed run — select the open PR whose
headRefOid == workflow_run.head_sha (and head branch + release/v* base), so a different/newer PR
on the same branch is never acted on. Topology test asserts the SHA-bound resolution.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ci): resolve backport PR from workflow_run.pull_requests, not branch name

Per review (PerishCode): use the run's authoritative pull_requests association as the source of
truth — select the entry whose base is release/* at exactly workflow_run.head_sha — instead of a
gh pr list --head branch-name lookup. Empty for forks (never auto-merged). Topology test updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 07:17:07 +00:00
..