Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions .github/workflows/post-merge-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ name: post-merge-verify
# P2-6(ADR-0041):自动合并的核心安全绳——合并到 main 后自动冒烟,失败自动
# revert(auto-merge 回滚)。把"事前人审"实质替换为"事后快速回滚":坏变更在
# main 的存活时间从"天"压缩到约 10 分钟级(验证+gate)。
# v1 范围:治理仓自检冒烟。业务仓接入(自定义冒烟命令)按 ADR-0041 后续逐仓
# 注册——注意 workflow_call 与 push 混用时 inputs 上下文在 push 事件不存在,
# 会在运行期引发 startup failure(0 job 实测),拆分时须避免。
on:
push:
branches: [main]
workflow_call:
inputs:
smoke:
description: "业务仓自定义冒烟命令(缺省跑治理仓自检:YAML/JSON/脚本语法)"
required: false
default: ""

permissions:
contents: read
Expand All @@ -23,15 +20,11 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: 冒烟验证(治理仓自检 / 业务仓自定义
- name: 冒烟验证(治理仓自检)
run: |
set -o pipefail
if [ -n "${{ inputs.smoke }}" ]; then
bash -c '${{ inputs.smoke }}'
Comment on lines -29 to -30

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Successful reverts trigger alerts 🐞 Bug ≡ Correctness

Once removing the invalid inputs.smoke references allows the workflow to run, the fallback alert
executes even after a successful automatic revert because failure() remains true from the failed
ancestor smoke job. Every successful auto-revert therefore creates a false “revert not executed”
P0 issue, potentially prompting an unnecessary manual rollback.
Agent Prompt
## Issue description
The now-operational workflow always enters the alert step after a smoke failure, even when the automatic revert succeeds, because `failure()` includes failures from ancestor jobs.

## Issue Context
Give the guard and automatic-revert steps IDs, then base the fallback condition on their explicit outcomes and the guard/App outputs. Preserve alerts for guard failures, token failures, blocked reverts, missing PRs, and failed revert commands without treating the expected upstream smoke failure as a revert failure.

## Fix Focus Areas
- .github/workflows/post-merge-verify.yml[43-46]
- .github/workflows/post-merge-verify.yml[58-103]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines -29 to -30

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

4. Revert rate limit bypass 🐞 Bug ☼ Reliability

The now-activated loop guard examines only the 20 newest PRs, so an auto-revert created earlier in
the same hour is missed whenever at least 20 newer PRs exist. A subsequent smoke failure can then
create another revert despite the stated one-per-hour limit.
Agent Prompt
## Issue description
The one-hour auto-revert rate-limit guard only checks the first 20 pull requests and can miss a qualifying revert PR on a later page.

## Issue Context
Fetch and aggregate all pages needed to cover the one-hour window before counting matching `[auto-revert]` titles. Ensure the resulting `RECENT` value is one aggregate integer rather than one count per page.

## Fix Focus Areas
- .github/workflows/post-merge-verify.yml[70-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

exit $?
fi
python3 - <<'EOF'
import glob, json, sys, yaml
import glob, json, yaml
files = glob.glob("governance/**/*.yaml", recursive=True) + glob.glob("standards/**/*.yaml", recursive=True)
for f in files:
yaml.safe_load(open(f, encoding="utf-8"))
Expand All @@ -57,26 +50,30 @@ jobs:
contents: write # revert 分支创建(REST revert 端点服务端建 ref)
pull-requests: write # revert PR + auto-merge
issues: write # 降级告警通道
env:
REPO: ${{ github.repository }}
SHA: ${{ github.sha }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
steps:
- name: 判定防回环闸
id: guard
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
HEAD_MSG: ${{ github.event.head_commit.message }}
run: |
# 闸 1:本次 commit 本身是 revert 类(标题含 [auto-revert])→ 不再嵌套
if grep -q "\[auto-revert\]" <<<"$HEAD_MSG"; then
echo "nested=true" >> "$GITHUB_OUTPUT"
else
echo "nested=false" >> "$GITHUB_OUTPUT"
fi
# 闸 2:本仓近 1 小时内已有 revert PR → 不重复(限频 1/h)
RECENT=$(gh api "repos/$REPO/pulls?state=all&sort=created&direction=desc&per_page=20" \
--jq '[.[] | select(.title | test("\\[auto-revert\\]")) | select(.created_at > (now - 3600 | todateiso8601))] | length')
echo "recent=$RECENT" >> "$GITHUB_OUTPUT"
echo "nested=$(grep -q '\[auto-revert\]' <<<"$HEAD_MSG" && echo true || echo false)" >> "$GITHUB_OUTPUT"
- name: App 令牌(AG-1 身份——revert PR 的 gate 须能被触发;GITHUB_TOKEN 造的 PR 不触发工作流)
id: app
continue-on-error: true # App 未安装本仓时降级为仅告警(不静默失败——下方有判定)
continue-on-error: true # App 未安装本仓时降级为仅告警(不静默——下方有判定)
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: 4632704
Expand All @@ -89,8 +86,6 @@ jobs:
if: steps.guard.outputs.nested != 'true' && steps.guard.outputs.recent == '0' && steps.app.outcome == 'success'
env:
GH_TOKEN: ${{ steps.app.outputs.token }}
REPO: ${{ github.repository }}
SHA: ${{ github.sha }}
run: |
set -o pipefail
PRN=$(gh api "repos/$REPO/commits/$SHA/pulls?per_page=5" --jq 'if length > 0 then .[0].number else "" end')
Expand All @@ -100,15 +95,19 @@ jobs:
fi
TITLE="[auto-revert] #$PRN:post-merge 冒烟失败(run ${{ github.run_id }})"
RESP=$(gh api -X POST "repos/$REPO/pulls/$PRN/revert" -f title="$TITLE" \
-f body="post-merge-verify 冒烟失败,自动回滚(ADR-0041)。原 PR #$PRN,commit ${SHA:0:8},失败 run:${{ github.server_url }}/${REPO}/actions/runs/${{ github.run_id }}" \
-f body="post-merge-verify 冒烟失败,自动回滚(ADR-0041)。原 PR #$PRN,commit ${SHA:0:8},失败 run:$RUN_URL" \
--jq '.number')
echo "revert PR #$RESP 已建,enable auto-merge"
gh pr merge "$RESP" --repo "$REPO" --auto --squash
- name: 降级/兜底告警(revert 不可用或被闸拦)
if: failure() || steps.app.outcome != 'success' || steps.guard.outputs.nested == 'true' || steps.guard.outputs.recent != '0'
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
gh issue create --repo "$REPO" --title "P0: post-merge 冒烟失败且自动 revert 未执行(run ${{ github.run_id }})" --body "合并 ${SHA:-HEAD} 后冒烟失败。自动 revert 未执行的原因:App 令牌不可用(未安装本仓?)/ 防回环闸(嵌套 revert 或 1h 限频)/ 无关联 PR。人工复核并回滚:${{ github.server_url }}/${REPO}/actions/runs/${{ github.run_id }}(ADR-0041)" --label auto-revert-alert || \
gh issue create --repo "$REPO" --title "P0: post-merge 冒烟失败且自动 revert 未执行(run ${{ github.run_id }})" --body "同上(label 创建失败兜底)"
gh issue create --repo "$REPO" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Fallback uses workflow token 📘 Rule violation ⛨ Security

The modified fallback creates GitHub issues using ${{ github.token }} instead of a
single-repository cloudbrid-agent token obtained through scripts/gh-app-token.sh. This bypasses
the required bot identity and authentication path.
Agent Prompt
## Issue description
The fallback GitHub issue operation authenticates with the workflow token rather than a cloudbrid-agent single-repository token issued by `scripts/gh-app-token.sh`.

## Issue Context
All authenticated GitHub operations must use the mandated script and must scope the resulting installation token to the current repository. If App authentication is unavailable, preserve a failed check rather than falling back to another identity.

## Fix Focus Areas
- .github/workflows/post-merge-verify.yml[102-113]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Alert creates repository issue 📘 Rule violation § Compliance

The modified bot fallback creates a repository issue, while the automation standard permits machine
feedback only through failed check runs or ordinary PR comments. This introduces an undocumented
feedback channel for the workflow.
Agent Prompt
## Issue description
The post-merge bot publishes failure feedback by creating a repository issue, which is not one of the feedback channels permitted by `standards/automation/`.

## Issue Context
The existing failed workflow check is already an approved feedback mechanism. Remove the issue creation or, where suitable and authenticated correctly, report through an ordinary PR comment.

## Fix Focus Areas
- .github/workflows/post-merge-verify.yml[102-113]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

--title "P0: post-merge 冒烟失败且自动 revert 未执行(run ${{ github.run_id }})" \
--body "合并 ${SHA:0:8} 后冒烟失败。自动 revert 未执行的原因:App 令牌不可用(未安装本仓?)/ 防回环闸(嵌套 revert 或 1h 限频)/ 无关联 PR。人工复核并回滚:$RUN_URL(ADR-0041)" \
--label P0 || \
gh issue create --repo "$REPO" \
--title "P0: post-merge 冒烟失败且自动 revert 未执行(run ${{ github.run_id }})" \
--body "同上(label 不存在兜底重试)"