mirror of
https://github.com/nexu-io/open-design.git
synced 2026-07-03 12:27:55 +08:00
feat(ci): auto-approve the release bot's own clean backport to satisfy release/v* review rule (#4682)
release/v* requires one approving review, so backport-automerge could not merge the bot's own backport PRs (an app can't approve its own PR). Approve as github-actions[bot] — a separate identity — under the SAME gates as the merge (author == release bot, same-repo, non-draft, head == the CI SHA, CI green). The diff was already reviewed + approved on main; the backport is a mechanical, conflict-free cherry-pick, so this auto-approval is scoped strictly to the release bot's verified backports, then merged with the App token. Topology test updated. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
23
.github/workflows/backport-automerge.yml
vendored
23
.github/workflows/backport-automerge.yml
vendored
@@ -17,6 +17,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write # github-actions[bot] approves the bot's own clean backport (Approve step)
|
||||
|
||||
jobs:
|
||||
followup:
|
||||
@@ -64,6 +65,28 @@ jobs:
|
||||
echo "head_oid=$(printf '%s' "$row" | jq -r '.headRefOid')"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Approve the clean backport (release bot, CI green)
|
||||
# release/v* requires 1 approving review. The diff was already reviewed + approved on
|
||||
# main; this is a mechanical, conflict-free cherry-pick by the release bot with green CI.
|
||||
# Approve as github-actions[bot] — a DIFFERENT identity than the App that authored the PR
|
||||
# (an author can't approve its own PR) — under the SAME bot-identity + SHA + CI gates as
|
||||
# the merge below, so only the release bot's own verified backports are auto-approved.
|
||||
if: >-
|
||||
${{ steps.pr.outputs.found == 'true'
|
||||
&& steps.pr.outputs.draft == 'false'
|
||||
&& steps.pr.outputs.author == 'open-design-release-bot[bot]'
|
||||
&& steps.pr.outputs.cross == 'false'
|
||||
&& steps.pr.outputs.head_oid == github.event.workflow_run.head_sha
|
||||
&& github.event.workflow_run.conclusion == 'success' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPO: ${{ github.repository }}
|
||||
NUM: ${{ steps.pr.outputs.number }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
gh pr review "$NUM" --repo "$REPO" --approve \
|
||||
--body "Auto-approved: clean cherry-pick by the release bot of code already reviewed on main, CI green. (release/v* requires one approval.)"
|
||||
|
||||
- name: Auto-merge clean backport on green CI
|
||||
# Guards (release/v* has no required checks, so this workflow IS the gate):
|
||||
# - author == the release bot and same-repo (not a fork) — so a stranger can't get a
|
||||
|
||||
@@ -236,6 +236,15 @@ describe("packaged smoke workflow", () => {
|
||||
expect(workflow).toContain("--squash");
|
||||
expect(workflow).toContain("--delete-branch");
|
||||
|
||||
// To satisfy release/v*'s one-approval rule, the bot's own clean backport is auto-approved by
|
||||
// github-actions[bot] (pull-requests: write) — under the same author==bot gate as the merge.
|
||||
expect(workflow).toContain("pull-requests: write");
|
||||
expect(workflow).toContain("gh pr review");
|
||||
expect(workflow).toContain("--approve");
|
||||
const approveStep = sectionBetween(workflow, "Approve the clean backport", "gh pr review");
|
||||
expect(approveStep).toContain("steps.pr.outputs.author == 'open-design-release-bot[bot]'");
|
||||
expect(approveStep).toContain("github.token");
|
||||
|
||||
// The Feishu failure path carries the same identity gates, so a fork / non-bot backport-*
|
||||
// PR can't spam the release group.
|
||||
const feishuStep = sectionBetween(workflow, "Notify Feishu on failed backport CI", "FEISHU_WEBHOOK");
|
||||
|
||||
Reference in New Issue
Block a user