PR 描述模板
指导 Agent 与人类把合并请求写成评审者可扫读的结构:动机与范围、实现摘要、风险与回滚、可复现测试与「希望别人重点看什么」——「做了什么」与「为什么」始终分开写。
好的 PR 正文降低首轮评审成本:读者先在一屏内判断「是否该我审、风险在哪、怎么验」,再下钻 diff。Agent 生成时应默认附带工单与设计文档链接,并区分「用户可见变更」与「纯内部重构」。
若含 UI,注明截图或录屏路径;若仅重构,强调行为不变与已有测试类型。大型变更附文件级导航或 commit 拆分说明,避免把认知负担全丢给评审者。
为何需要结构化描述
非结构化正文常见问题是动机埋在中间、测试步骤复制粘贴不可执行、风险与回滚缺失。模板的价值不是字数多,而是固定扫描顺序,让评审与 CI 失败时的排查都更快。
- 顶部用一两句写清「解决什么问题 / 对谁有价值」,再展开实现。
- 明确写出「本 PR 刻意不做的事」,减少范围蔓延争议。
- 需要 SRE、DBA 或安全预审的项在正文或 checklist 中单列,避免口头约定遗漏。
PR 生命周期(从草稿到上线)
描述正文应与阶段匹配:草稿期侧重动机与方案取舍;评审期补充讨论结论;合并前后补全部署顺序、监控与回滚。下图是常见平台无关的简化流程,可在团队 SKILL 中替换为具体工具名与门禁名称。
[ 本地开发 / 小步 commit ]
│
▼
[ 开 PR:标题 + 结构化正文 ]
│
▼
┌─────────────────────────────┐
│ 自动化:lint / test / build │
└─────────────────────────────┘
│
┌────┴────┐
▼ ▼
[ CI 红 ] [ CI 绿 ]
│ │
▼ ▼
修代码/更新描述 [ 人工评审 + 讨论 ]
│ │
└────────┬────────┘
▼
[ 批准 + 满足分支保护 ]
│
▼
[ 合并进主线 ]
│
▼
[ 部署 / 特性开关 / 监控验证 ]
│
┌──────┴──────┐
▼ ▼
[ 观测正常 ] [ 回滚 / hotfix ]
│ │
└──────┬──────┘
▼
[ 关闭工单 / 复盘 ]
推荐章节与内容要点
下列标题可按仓库习惯改名,但语义建议保留。Agent 输出时应用列表与短段落,避免大段散文。
- 背景 / 目标:链到 issue、RFC 或事故复盘;说明成功标准。
- 实现要点:关键算法、API 变更、数据迁移步骤;对外契约变更需显式标出。
- 风险与回滚:特性开关名、数据库向前/向后兼容、灰度依赖。
- 测试:单元 / 集成 / 手工分条;优先贴可复制的命令或脚本路径。
- 合并后:部署顺序、需关注的仪表盘、告警静默窗口(若有)。
<!-- 完整 PR 描述模板(保存为 .github/pull_request_template.md)-->
## 背景 / 目标
<!-- 解决什么问题?关联 Issue/RFC/事故复盘 -->
Closes #
## 变更类型
- [ ] Feature(新功能)
- [ ] Bug Fix(缺陷修复)
- [ ] Hotfix(紧急补丁,需关联 on-call 工单)
- [ ] Refactor(重构,行为不变)
- [ ] Docs(文档)
## 实现要点
<!-- 关键设计决策、API 变更、数据迁移步骤 -->
-
## 风险与回滚
- 特性开关(若有):`billing.new-checkout-flow`(默认 off)
- 数据库变更:[ ] 已确认向前兼容 / [ ] 含不可逆迁移(需审批)
- 回滚方式:关闭特性开关 / kubectl rollout undo / 人工操作
## 测试
<!-- 可复制的命令 -->
```bash
pnpm test --filter=auth
pnpm test:e2e -- --spec cypress/e2e/checkout.cy.ts
```
- [ ] 单元测试已通过(覆盖 flag=ON 和 flag=OFF 双路径)
- [ ] 集成测试通过
- [ ] 手工验证:[步骤描述]
## 合并后
- 部署顺序:先合并再部署(无数据库迁移) / 先迁移再发布
- 监控面板:https://grafana.example.com/d/xxx
- 告警静默:发布后观察 30 min
## 审查焦点
<!-- 希望评审者重点关注的文件或决策 -->
- `src/auth/token-refresh.ts`:并发锁实现是否合理?
- `migrations/V20240410__*.sql`:迁移是否可回滚?
评审者视角:希望看到什么
主动写出「审查焦点」——例如「请重点看权限校验与缓存失效」——比让评审者自己猜更高效。若存在已知技术债,注明是本次偿还还是刻意遗留并附后续工单。
- 安全相关:输入边界、鉴权路径、敏感日志是否脱敏。
- 性能:热点路径、N+1、大表扫描或批处理规模。
- 可维护性:是否引入新依赖、配置项命名是否与现有约定一致。
与 Agent 协作
SKILL 应要求模型在写 PR 正文前读取:目标分支约定、团队测试命令、是否 squash、以及 CODEOWNERS 可能触发的路径。生成后让人类快速改「业务语境」与「发布窗口」两类信息即可。
# 不同 PR 类型的差异化要求
# Feature PR
# - 必须:背景 + 实现要点 + 测试步骤(含特性开关状态)
# - 可选:UI 截图 / 录屏(若有 UI 变更)
# - 测试命令示例:pnpm test --filter=affected
# Bug Fix PR
# - 必须:能复现问题的最小步骤 + 修复说明
# - 必须:关联原始 Bug Report Issue
# - 测试命令示例:pnpm test -- --testNamePattern="token refresh"
# Hotfix PR(紧急补丁)
# - 必须:关联 on-call 工单 / 事故 ID(如 INC-XXXX)
# - 必须:影响面评估 + 回滚步骤(写清楚,发布时紧张容易遗忘)
# - 审批:需要 2+ approvals + 安全/SRE 签字(CODEOWNERS 强制)
# Refactor PR
# - 必须:声明「行为不变」并解释如何验证(哪些测试覆盖了行为)
# - 必须:说明为什么现在重构(减少未来 PR 摩擦)
# - 避免:在 refactor PR 中混入功能变更(应拆分)
# 大 PR 拆分原则(diff > 400 行时触发)
# - 在正文写「已拆分为 #xxx #yyy」并指向父工单
# - 每个子 PR 独立可合并、独立可回滚
# - 用特性开关隔离未完成功能
约束示例:禁止编造不存在的 issue 链接;若 diff 中无测试变更,须在正文说明「已有用例覆盖」或「为何无需新测」;UI 变更无截图时须标注「待补」而非静默省略。
合并前自检与章节要点生成
下方勾选状态保存在本机浏览器(localStorage,键名 vvskill-pr-desc-checklist-v1);章节文本与生成结果保存在 vvskill-pr-desc-section-builder-v1。不上传服务器。
合并前自检
章节要点 → Markdown
每框一行一条要点,或空行分隔;将生成二级标题与无序列表,可直接贴入 PR。
SKILL 大纲(YAML)
供 Agent 引用时保持字段名与团队模板一致;可按 monorepo / 多服务仓库增加「影响范围」小节。
---
name: pr-description
description: 结构化 PR 正文:背景、实现、风险、测试、审查焦点与合并后操作
version: 2.0
---
# PR 模板章节(必选)
## 背景 / 目标 (Closes #issue,成功标准)
## 变更类型 (Feature/Fix/Hotfix/Refactor/Docs)
## 实现要点 (关键决策、API 变更、数据迁移)
## 风险与回滚 (特性开关名、DB 兼容性、回滚命令)
## 测试 (可复制命令 + 双路径检查清单)
## 合并后 (部署顺序、监控面板链接)
## 审查焦点 (希望评审者重点看的文件/决策)
# 按类型差异化要求
Feature: 背景 + 实现 + 测试(含 flag=ON/OFF 双路径)
Bug Fix: 复现步骤 + 修复说明 + 关联 Issue
Hotfix: 关联 on-call 工单 + 影响面 + 回滚步骤(2+ approvals)
Refactor: 声明行为不变 + 验证方式(禁止混入功能变更)
# CODEOWNERS 示例(.github/CODEOWNERS)
/src/auth/ @security-team @core-team
/src/payment/ @payment-team @security-team
/infra/ @sre-team
*.sql @dba-team
# 大 PR 拆分触发条件
diff > 400 行 → 必须在正文写「已拆分为 #xxx #yyy」