|
| 1 | +--- |
| 2 | +name: "create-release-note" |
| 3 | +description: "从 PR/commit 中自动生成结构化的 Release Notes,并可选创建 GitHub Draft Release" |
| 4 | +usage: "/create-release-note <version> [prev-version]" |
| 5 | +--- |
| 6 | + |
| 7 | +# Create Release Note Command |
| 8 | + |
| 9 | +## 功能说明 |
| 10 | + |
| 11 | +自动从 PR、commit 和 Issue 中收集变更信息,按模块和类型分类,生成符合项目格式的 Release Notes。支持创建 GitHub Draft Release。 |
| 12 | + |
| 13 | +对于 x.y.0 版本,支持合并前一 minor 系列的已发布 release notes,无需重复计算。 |
| 14 | + |
| 15 | +## 用法 |
| 16 | + |
| 17 | +```bash |
| 18 | +/release-notes <version> # 自动推断上一版本 |
| 19 | +/release-notes <version> <prev-version> # 手动指定版本范围 |
| 20 | +``` |
| 21 | + |
| 22 | +例如: |
| 23 | +```bash |
| 24 | +/create-release-note 3.6.3 # 自动推断上一版本为 3.6.2 |
| 25 | +/create-release-note 3.6.3 3.6.2 # 手动指定范围 |
| 26 | +/create-release-note 3.7.0 # x.y.0 版本:合并 3.6.x 系列的所有 release notes |
| 27 | +``` |
| 28 | + |
| 29 | +## 参数说明 |
| 30 | + |
| 31 | +- `<version>`: 当前发布版本号,格式为 `X.Y.Z`(必需) |
| 32 | +- `<prev-version>`: 上一版本号,格式为 `X.Y.Z`(可选,不提供则自动推断) |
| 33 | + |
| 34 | +参数来源:`$ARGUMENTS` |
| 35 | + |
| 36 | +## 执行步骤 |
| 37 | + |
| 38 | +步骤 1-3 为公共步骤,步骤 3 根据版本类型分流: |
| 39 | +- **合并路径**(PATCH == 0,如 `3.7.0`):步骤 4-7 → 跳到步骤 14 |
| 40 | +- **常规路径**(PATCH > 0,如 `3.6.3`):步骤 8-13 → 继续步骤 14 |
| 41 | + |
| 42 | +步骤 14-15 为公共步骤。 |
| 43 | + |
| 44 | +### 步骤 1:解析参数 |
| 45 | + |
| 46 | +从 `$ARGUMENTS` 中提取参数。支持两种形式: |
| 47 | +- 单参数:`<version>` — 当前版本号 |
| 48 | +- 双参数:`<version> <prev-version>` — 当前版本号和上一版本号 |
| 49 | + |
| 50 | +**版本号格式验证**: |
| 51 | +- 必须匹配 `X.Y.Z` 格式(X、Y、Z 均为非负整数) |
| 52 | +- 如果格式不正确,报错退出:`错误:版本号格式不正确,期望格式为 X.Y.Z(例如 3.6.3)` |
| 53 | + |
| 54 | +### 步骤 2:确定版本范围 |
| 55 | + |
| 56 | +**当前版本 tag**: `v<version>`(如 `v3.6.3`) |
| 57 | + |
| 58 | +**上一版本 tag 推断逻辑**(仅当未指定 `<prev-version>` 时): |
| 59 | + |
| 60 | +```bash |
| 61 | +# 获取所有已排序的 tag |
| 62 | +git tag --sort=-v:refname |
| 63 | +``` |
| 64 | + |
| 65 | +- 如果 PATCH > 0(如 `3.6.3`):查找同一 minor 系列中的前一个 tag(如 `v3.6.2`) |
| 66 | +- 如果 PATCH == 0(如 `3.6.0`):查找前一个 minor 系列的最后一个 tag(如 `v3.5.x` 中最大的) |
| 67 | + |
| 68 | +**验证 tag 存在**: |
| 69 | + |
| 70 | +```bash |
| 71 | +git rev-parse v<version> |
| 72 | +git rev-parse v<prev-version> |
| 73 | +``` |
| 74 | + |
| 75 | +如果任一 tag 不存在,报错退出:`错误:Tag v<version> 不存在,请确认 tag 已创建` |
| 76 | + |
| 77 | +### 步骤 3:判断版本类型并选择路径 |
| 78 | + |
| 79 | +根据版本号的 PATCH 部分选择不同的生成路径: |
| 80 | + |
| 81 | +- **如果 PATCH == 0**(如 `3.7.0`)→ 走**合并路径**,从步骤 4 开始 |
| 82 | +- **如果 PATCH > 0**(如 `3.6.3`)→ 走**常规路径**,从步骤 8 开始 |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +### 合并路径(PATCH == 0,x.y.0 版本) |
| 87 | + |
| 88 | +### 步骤 4:查找前一 minor 系列的所有已发布 release |
| 89 | + |
| 90 | +```bash |
| 91 | +gh release list --limit 50 --json tagName,isDraft,isPrerelease |
| 92 | +``` |
| 93 | + |
| 94 | +从结果中筛选满足以下条件的条目: |
| 95 | +- `tagName` 以 `vX.(Y-1).` 开头(例如版本 `3.7.0` 则筛选 `v3.6.` 开头) |
| 96 | +- `isDraft == false` |
| 97 | +- `isPrerelease == false` |
| 98 | + |
| 99 | +如果未找到任何已发布的 release,提示用户并回退到常规路径(步骤 8)。 |
| 100 | + |
| 101 | +### 步骤 5:按版本号升序获取各 release body |
| 102 | + |
| 103 | +对步骤 4 筛选出的每个 release tag,按版本号升序获取其内容: |
| 104 | + |
| 105 | +```bash |
| 106 | +gh release view v<tag> --json body --jq .body |
| 107 | +``` |
| 108 | + |
| 109 | +### 步骤 6:合并所有 release body |
| 110 | + |
| 111 | +将各版本的 release notes 合并为一份完整文档: |
| 112 | + |
| 113 | +1. **按版本顺序拼接**:按 `v3.6.1`、`v3.6.2`、`v3.6.3` ... 的顺序处理 |
| 114 | +2. **同平台同类型条目合并**:将各版本中相同平台(如 FIT Function Platform)相同类型(如 Enhancement)的条目合并到一起 |
| 115 | +3. **去重 Contributors**:合并所有 `❤️ Contributors` 段落中的贡献者,去重后按贡献量(出现次数)降序排列 |
| 116 | + |
| 117 | +### 步骤 7:生成 Overview |
| 118 | + |
| 119 | +x.y.0 版本始终视为 Major release: |
| 120 | + |
| 121 | +1. **在顶部添加 `🌟 Overview` 总结段落**:AI 根据合并内容生成 2-3 句话概括整个 minor 系列的核心主题和亮点 |
| 122 | +2. **每个平台添加 `🚀 Features Overview` 要点列表**:从该平台的 Enhancement 条目中提炼 3-5 个关键特性要点 |
| 123 | + |
| 124 | +**完成后跳到步骤 14。** |
| 125 | + |
| 126 | +--- |
| 127 | + |
| 128 | +### 常规路径(PATCH > 0) |
| 129 | + |
| 130 | +### 步骤 8:收集合并的 PR |
| 131 | + |
| 132 | +**主要数据源** — 获取两个 tag 之间的日期范围,然后用 `gh` CLI 查询合并的 PR: |
| 133 | + |
| 134 | +```bash |
| 135 | +# 获取两个 tag 的日期 |
| 136 | +git log v<prev-version> --format=%aI -1 |
| 137 | +git log v<version> --format=%aI -1 |
| 138 | + |
| 139 | +# 获取目标分支(从当前版本号推断,如 3.6.x) |
| 140 | +# 分支名格式: X.Y.x |
| 141 | + |
| 142 | +# 获取合并到目标分支的 PR |
| 143 | +gh pr list --state merged --base <branch> \ |
| 144 | + --json number,title,body,author,labels,mergedAt,url \ |
| 145 | + --limit 200 --search "merged:YYYY-MM-DD..YYYY-MM-DD" |
| 146 | +``` |
| 147 | + |
| 148 | +**补充数据源** — 获取没有关联 PR 的直接 commit: |
| 149 | + |
| 150 | +```bash |
| 151 | +git log v<prev-version>..v<version> --format="%H %s" --no-merges |
| 152 | +``` |
| 153 | + |
| 154 | +对比 PR 列表和 commit 列表,找出没有关联 PR 的 commit(这些 commit 也应纳入 release notes)。 |
| 155 | + |
| 156 | +### 步骤 9:收集关联的 Issue |
| 157 | + |
| 158 | +从每个 PR 的 body 中提取关联的 Issue: |
| 159 | +- 匹配模式:`Closes #N`、`Fixes #N`、`Resolves #N`(不区分大小写) |
| 160 | +- 也匹配:`close #N`、`fix #N`、`resolve #N` 及其复数形式 |
| 161 | + |
| 162 | +对每个提取到的 Issue 编号: |
| 163 | + |
| 164 | +```bash |
| 165 | +gh issue view <N> --json number,title,labels,url |
| 166 | +``` |
| 167 | + |
| 168 | +收集 Issue 详情用于丰富 release notes 的描述。 |
| 169 | + |
| 170 | +### 步骤 10:分类 — 按模块分组 |
| 171 | + |
| 172 | +根据以下**优先级**判断每个 PR/commit 所属模块: |
| 173 | + |
| 174 | +| 优先级 | 判断依据 | 示例 | |
| 175 | +|--------|----------|------| |
| 176 | +| 1 | PR title 中的模块标签 `[fit]`, `[FEL]`, `[waterflow]` | `[fit] 修复空指针` → FIT | |
| 177 | +| 2 | Conventional commit scope `feat(fit):`, `fix(waterflow):` | `feat(waterflow): xxx` → Waterflow | |
| 178 | +| 3 | PR 变更文件路径(使用 `gh pr view <N> --json files`) | `framework/fel/**` → FEL | |
| 179 | +| 4 | 默认归入 FIT Function Platform | | |
| 180 | + |
| 181 | +**模块到平台的映射**: |
| 182 | + |
| 183 | +| 关键词 / 路径 | 平台名称 | |
| 184 | +|---------------|----------| |
| 185 | +| `fit`, `python`, `docker`, `fit-launcher`, `framework/fit/**` | **FIT Function Platform** | |
| 186 | +| `fel`, `FEL`, `framework/fel/**` | **FIT Expression for LLM** | |
| 187 | +| `waterflow`, `framework/waterflow/**` | **Waterflow Flow Scheduling Platform** | |
| 188 | +| `claude`, `.claude/`, `.ai-agents/`, AI 相关配置 | **🤖 AI Development Configuration** | |
| 189 | + |
| 190 | +### 步骤 11:分类 — 按类型分组 |
| 191 | + |
| 192 | +根据 PR title 的 conventional commit type 分类: |
| 193 | + |
| 194 | +| PR Title 前缀 / 特征 | 分类 | |
| 195 | +|----------------------|------| |
| 196 | +| `feat`, `perf`, `refactor`, `chore(deps)`, 依赖升级 | ✨ Enhancement | |
| 197 | +| `fix` | ✅ Bugfix | |
| 198 | +| `docs` | 📚 Documentation(如果条目少于 3 个,并入 Enhancement) | |
| 199 | + |
| 200 | +### 步骤 12:判断发布级别 |
| 201 | + |
| 202 | +根据变更数量和性质判断输出详细程度: |
| 203 | + |
| 204 | +- **Major release**(合并 PR > 15 个): |
| 205 | + - 生成 `🌟 Overview` 总结段落(2-3 句话概括本次发布的核心主题) |
| 206 | + - 每个平台生成 `🚀 Features Overview` 要点列表 |
| 207 | +- **Regular release**: |
| 208 | + - 直接列出 Enhancement / Bugfix 条目,不加 Overview |
| 209 | + |
| 210 | +### 步骤 13:生成 Release Notes |
| 211 | + |
| 212 | +按照项目已有格式输出 markdown。完整模板: |
| 213 | + |
| 214 | +```markdown |
| 215 | +## FIT Function Platform |
| 216 | + |
| 217 | +### ✨ Enhancement |
| 218 | + |
| 219 | +- [fit] 描述内容 by @author1 and @author2 in [#123](url) |
| 220 | +- Upgrade xxx from v1 to v2 by @author in [#456](url) |
| 221 | + |
| 222 | +### ✅ Bugfix |
| 223 | + |
| 224 | +- [fit] 修复xxx问题 by @author in [#100](issue-url) and [#789](pr-url) |
| 225 | + |
| 226 | +## FIT Expression for LLM |
| 227 | + |
| 228 | +### ✨ Enhancement |
| 229 | + |
| 230 | +- [FEL] 描述内容 by @author in [#234](url) |
| 231 | + |
| 232 | +## Waterflow Flow Scheduling Platform |
| 233 | + |
| 234 | +### ✨ Enhancement |
| 235 | + |
| 236 | +- [waterflow] 描述内容 by @author in [#345](url) |
| 237 | + |
| 238 | +## 🤖 AI Development Configuration |
| 239 | + |
| 240 | +### ✨ Enhancement |
| 241 | + |
| 242 | +- 描述内容 by @author in [#567](url) |
| 243 | + |
| 244 | +## ❤️ Contributors |
| 245 | + |
| 246 | +@contributor1, @contributor2, @contributor3 |
| 247 | +``` |
| 248 | + |
| 249 | +**格式规则**(从现有 release notes 中提炼): |
| 250 | + |
| 251 | +1. **条目格式**: `- [module] 描述 by @author1 and @author2 in [#N](url)` |
| 252 | +2. **关联 Issue 和 PR**: `in [#Issue](issue-url) and [#PR](pr-url)` |
| 253 | +3. **没有关联 PR 的 commit**: 省略 `in [#N]` 部分,直接写描述 |
| 254 | +4. **描述内容**: 优先使用 PR title,去掉 `type(scope):` 前缀,首字母大写 |
| 255 | +5. **贡献者列表**: 去重,按贡献量(PR 数量)降序排列 |
| 256 | +6. **空平台**: 如果某个平台没有任何变更,不输出该平台的章节 |
| 257 | +7. **多作者**: 如果 PR 有多个 co-author,用 `and` 连接:`by @a and @b` |
| 258 | + |
| 259 | +--- |
| 260 | + |
| 261 | +### 公共步骤 |
| 262 | + |
| 263 | +### 步骤 14:展示并确认 |
| 264 | + |
| 265 | +将生成的 release notes **完整输出**给用户查看。 |
| 266 | + |
| 267 | +然后询问用户: |
| 268 | +1. 是否需要调整内容(修改描述、调整分类、增删条目等) |
| 269 | +2. 是否创建 GitHub Draft Release |
| 270 | + |
| 271 | +如果用户要求调整,根据反馈修改后重新输出。 |
| 272 | + |
| 273 | +### 步骤 15:创建 Draft Release |
| 274 | + |
| 275 | +用户确认后,将 release notes 写入临时文件,然后创建 Draft Release: |
| 276 | + |
| 277 | +```bash |
| 278 | +gh release create v<version> \ |
| 279 | + --title "v<version>" \ |
| 280 | + --notes-file /tmp/release-notes-v<version>.md \ |
| 281 | + --target <release-branch-or-tag> \ |
| 282 | + --draft |
| 283 | +``` |
| 284 | + |
| 285 | +输出结果: |
| 286 | +``` |
| 287 | +✅ Draft Release 已创建 |
| 288 | +
|
| 289 | +- Release URL: <draft-release-url> |
| 290 | +- 版本: v<version> |
| 291 | +- 状态: Draft(草稿) |
| 292 | +
|
| 293 | +⚠️ 请在 GitHub 上最终审核并发布: |
| 294 | +1. 打开上述 URL |
| 295 | +2. 检查 Release Notes 内容 |
| 296 | +3. 确认无误后点击 "Publish release" |
| 297 | +``` |
| 298 | + |
| 299 | +## 注意事项 |
| 300 | + |
| 301 | +1. **需要 `gh` CLI**:本命令依赖 GitHub CLI(`gh`),请确保已安装并认证 |
| 302 | +2. **Tag 必须已存在**:运行本命令前,确保 `v<version>` 和上一版本的 tag 已创建(通常由 `/release` 命令完成) |
| 303 | +3. **Draft 模式**:创建的是草稿 Release,不会自动发布,需要人工审核后在 GitHub 上发布 |
| 304 | +4. **PR 搜索范围**:基于日期范围搜索,可能包含少量超出范围的 PR,命令会尽力过滤 |
| 305 | +5. **模块分类准确性**:自动分类基于 title/scope/文件路径推断,复杂 PR 可能需要人工调整 |
| 306 | +6. **x.y.0 合并路径**:依赖前一 minor 系列的 release 已在 GitHub 上发布(非 Draft),如果没有已发布的 release 则回退到常规路径 |
| 307 | + |
| 308 | +## 错误处理 |
| 309 | + |
| 310 | +- **版本号格式错误**:提示正确格式并退出 |
| 311 | +- **Tag 不存在**:提示确认 tag 已创建(可能需要先执行 `/release`) |
| 312 | +- **`gh` CLI 未安装或未认证**:提示安装/认证方法 |
| 313 | +- **无合并 PR**:提示版本范围内没有找到合并的 PR,建议检查 tag 和分支 |
| 314 | +- **GitHub API 限流**:提示稍后重试 |
| 315 | +- **x.y.0 无已发布 release**:提示前一 minor 系列没有已发布的 release,回退到常规路径 |
| 316 | + |
| 317 | +## 相关命令 |
| 318 | + |
| 319 | +- `/release <version>` - 执行版本发布流程(创建 tag 和发布分支) |
| 320 | +- `/commit` - 提交代码 |
| 321 | +- `/create-pr` - 创建 Pull Request |
0 commit comments