docs: §13/§18/§23 更新 synchronize fallback + merge 通知

This commit is contained in:
cfdaily
2026-06-12 08:41:17 +08:00
parent f4fc941bd1
commit 40efa1c623
3 changed files with 65 additions and 13 deletions
+36 -9
View File
@@ -28,6 +28,7 @@
|---|---|---|---|---|
| E1 | PR 更新(push 新 commit)→ 通知 reviewer | `pull_request.synchronize` | **高** | review 驳回→修改→重 review 的关键闭环 |
| ~~E2~~ | ~~PR 合并通知~~ | ~~已删除~~ | ~~—~~ | ~~和 §22 CD 成功通知重叠,已删~~ |
| E2 | PR 合并 → 通知 PR 作者 | `pull_request` (closed+merged) | **高** | PR #38 恢复:CD 通知语义不同(部署状态 vs 合并信息),文档 PR 无 CD 流程仍需通知 |
| E3 | Review 评论(COMMENTED)→ 通知 PR 作者 | `pull_request_review` (COMMENTED) | 中 | reviewer 讨论提问,作者应知道 |
| E4 | PR 上普通评论 → 通知相关人 | `issue_comment` (on PR) | 低 | 非关键路径 |
@@ -64,17 +65,42 @@ async def _handle_pull_request(payload: Dict[str, Any]) -> None:
新增 `_handle_pr_synchronize`
1. 从 payload 取 PR 信息(number、title、author、head sha
2. 查询最近一次 reviewGitea API `GET /repos/{owner}/{repo}/pulls/{number}/reviews`)取 reviewer
3. 如果没有 review 记录(首次 push 后 reviewer 还没 review),跳过(opened 事件已经通知过了
3. 如果没有 review 记录(`_fetch_latest_reviewer()` 返回 None),fallback 到默认 reviewer `simayi-challenger`,而非跳过通知(PR #38 改动:确保无 review 历史时也能通知默认审查者
4. 渲染 `review_updated.md` 模板,发送 Mail 给 reviewer
**关键设计决策**
- 不用 `requested_reviewers`(可能为空),用最近 review 的提交者
- 只在有 review 历史时才通知(避免 opened + synchronize 重复通知)
- review 历史时 fallback 到默认 reviewer `simayi-challenger`PR #38避免 opened + synchronize 间隔较短时 reviewer 未收到任何通知)
- Mail from 用 `system`
### ~~Handler 2PR 合并通知~~ — 已删除
### Handler 2`_handle_pr_closed`PR 合并通知)— PR #38 恢复
> 司马懿 review 指出与 §22 CD 成功通知重叠。CD 成功通知已隐含合并信息,无需单独发 merged 通知。
**触发**`pull_request` 事件 + `action=closed` + `merged=true`
**通知对象**PR 作者
**实现**
修改 `_handle_pull_request` 的 action 分发,新增 `closed` 分支:
```python
async def _handle_pull_request(payload: Dict[str, Any]) -> None:
action = payload.get("action", "")
if action == "opened":
await _handle_pr_opened(payload)
elif action == "synchronize":
await _handle_pr_synchronize(payload)
elif action == "closed" and payload.get("pull_request", {}).get("merged"):
await _handle_pr_closed(payload)
# 其他 action 忽略
```
新增 `_handle_pr_closed`
1. 从 payload 取 PR 信息(number、title、merged_by
2. `merged_by` 优先从 `payload["pull_request"]["merged_by"]` 取,若为空则 fallback 到 `payload["sender"]`PR #38:兼容不同 Gitea 版本和 merge 方式)
3. 渲染 `pr_merged.md` 模板,发送 Mail 给 PR 作者
**恢复说明**:此前因与 §22 CD 成功通知重叠而删除。但实际场景中 CD 通知发的是部署状态,PR 作者更关心的是"谁帮我 merge 了"这个信息,两者语义不同。且 CD 流程不一定每次都触发(如文档 PR),merge 通知仍需独立存在。(PR #38 恢复)
### 新增 Handler 3review COMMENTED 处理
@@ -101,7 +127,7 @@ async def _handle_pull_request(payload: Dict[str, Any]) -> None:
| 模板文件 | 变量 | 说明 |
|---|---|---|
| `review_updated.md` | repo, pr_number, pr_title, pr_author, branch, new_sha, reviewer | PR 有新 commit,请重新 review |
| ~~`pr_merged.md`~~ | ~~已删除~~ | ~~—~~ |
| `pr_merged.md` | repo, pr_number, pr_title, pr_author, merged_by | PR 已合并,通知作者(PR #38 恢复) |
| `review_comment.md` | repo, pr_number, pr_title, reviewer, comment_body | reviewer 提交了评论 |
### `_EVENT_HANDLERS` 无需改动
@@ -122,9 +148,9 @@ async def _handle_pull_request(payload: Dict[str, Any]) -> None:
| 文件 | 改动 |
|---|---|
| `src/api/toolchain_routes.py` | 修改 `_handle_pull_request`(扩展 action 分发)+ 新增 `_handle_pr_synchronize` + 修改 `_handle_pull_request_review`(支持 COMMENTED |
| `src/api/toolchain_routes.py` | 修改 `_handle_pull_request`(扩展 action 分发 + closed 分支+ 新增 `_handle_pr_synchronize` + `_handle_pr_closed` + 修改 `_handle_pull_request_review`(支持 COMMENTED |
| `templates/toolchain/review_updated.md` | 新增 |
| ~~`templates/toolchain/pr_merged.md`~~ | ~~已删除~~ |
| `templates/toolchain/pr_merged.md` | 新增(PR #38 恢复) |
| `templates/toolchain/review_comment.md` | 新增 |
| `src/daemon/toolchain_templates.py` | `_TEMPLATE_MAP` 新增 3 个映射 |
| `docs/design/23-toolchain-pr-lifecycle.md` | 本文档 |
@@ -134,8 +160,9 @@ async def _handle_pull_request(payload: Dict[str, Any]) -> None:
`sanguo/moziplus-v2` 测试仓库上 E2E 验证:
1. **synchronize**:创建 PR → review 驳回 → push 新 commit → 验证 reviewer 收到"请重新 review" Mail
~~2. merged~~:已删除
3. **COMMENTED**review 提交纯评论 → 验证 PR 作者收到通知
2. **synchronize fallback**PR #38):创建 PR → push commit(无 review 历史)→ 验证默认 reviewer (`simayi-challenger`) 收到通知
3. **merge 通知**PR #38 恢复):PR merge → 验证 PR 作者收到合并通知 Mail
4. **COMMENTED**:review 提交纯评论 → 验证 PR 作者收到通知
## 风险评估