# Gitea 分支保护的 required check 名跟 workflow 重命名/合并不会自动同步

**日期**: 2026-04-29
**上下文**: PR #166 把 `agent-assets-check.yml` 删了并入 `quality-gates.yml`（job 名 `verify-agent-assets`）。develop / staging 分支保护规则里仍把旧 context 名 `agent-assets-check / verify-agent-assets (pull_request)` 当成 required check。

## 现象

合并到 develop 当天没立刻爆——因为我们用 `scripts/ops/gitea-pr-merge.py` 合并，脚本在 merge 前 PATCH 把 `enable_status_check: True → False` 暂时关掉再合，避免被 stale required check 卡住。

但**任何人通过 Gitea web UI 直接合 PR**（不走脚本）就会卡死：
- 旧 required 名 `agent-assets-check / verify-agent-assets` 永远不会出现（workflow 已删）
- Gitea 等"required check 通过"等到天荒地老
- 用户看不到为什么不能合，只看到一个永远 pending 的 check

## 根因

Gitea / GitHub Actions 的 required status check 列表是**字符串字面量**（`"<workflow-name> / <job-name> (<event>)"`）存在分支保护规则里，跟 workflow 文件本身没绑定。重命名 workflow / job / 删除 workflow 文件，required check 列表**不会自动迁移**。

## 检测命令

```bash
# 查 develop 当前 required
curl -s -H "Authorization: token $GITEA_API_TOKEN" \
  "http://43.130.59.228/api/v1/repos/FFAIWorkspace/workspace/branch_protections/develop" \
  | jq -r '.status_check_contexts[]'

# 跟实际 workflow 文件 + job 名对比，找漂移
ls .gitea/workflows/
grep -E "^  [a-z][a-z0-9_-]*:" .gitea/workflows/<file>.yml
```

## 修复

```python
import json, urllib.request
data = json.dumps({"status_check_contexts": [
    "quality-gates / verify-agent-assets (pull_request)",
    "quality-gates / build-check (pull_request)",
    "quality-gates / migration-file-count (pull_request)",
    "quality-gates / contract-check (pull_request)",
    "quality-gates / backend-integration (pull_request)",
]}).encode()
req = urllib.request.Request(
    "http://43.130.59.228/api/v1/repos/FFAIWorkspace/workspace/branch_protections/develop",
    data=data, headers={"Authorization": f"token {TOKEN}", "Content-Type": "application/json"},
    method="PATCH"
)
urllib.request.urlopen(req)
```

## 副作用：影响所有未关闭的 PR

PATCH 完之后，**之前已开 + CI 已跑**的 PR 仍然带着旧名状态（status 是 SHA-keyed）。它们要重新合并需要：
- 推空 commit `git commit --allow-empty -m "trigger ci"` 触发同步事件 → CI 重跑 → 新名字状态写入
- 或者 rebase + force push 同效

PATCH 前最好先看一眼 `GET /pulls?state=open` 知道有哪些 PR 会受影响，提前提示作者。

## 流程改进：每次重命名 / 合并 workflow 必须做

CI workflow 文件改动 PR 的 checklist 里加：

- [ ] 是否新增 / 删除 / 重命名了 workflow 文件？
- [ ] 是否新增 / 删除 / 重命名了 job？
- [ ] 是 → 同步检查并 PATCH 三层分支保护（develop / staging / production）的 required check 列表
- [ ] 是 → 通知所有 open PR 作者重跑 CI

理想做法：把这个检查写进 `docs/standards/05-development-workflow.md` 的 PR 合并门禁段落，下次发生时能被注意到。

## 关联

- `docs/ops/02-gitea-config.md` § 4 必需状态检查（已更新到对齐状态）
- `docs/standards/05-development-workflow.md` 合并门禁清单（已更新为列举法，避免数字漂移；建议加上"重命名 job 时同步 PATCH 保护"的条款）
- `scripts/ops/gitea-pr-merge.py` —— 通过 relax 三字段绕过 stale check，但不是治根方案
