redis-py 发布说明生成指南:PR 标签驱动的 Release Notes 草稿工作流
【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py
redis-py 从 4.0.0 起不再维护 CHANGES 文件式的历史记录,所有变更都沉淀在 GitHub Releases 中(见 CHANGES 文件开头的说明)。本文基于仓库内置的generate-release-notes技能完整文档(.claude/skills/generate-release-notes/SKILL.md 与其主体 .agents/skills/generate-release-notes/SKILL.md,以及两个权威 references 文件),系统讲解如何为 redis-py 生成一份与官方发布结构完全一致的 Release Notes 草稿:从确定发布分支与区间、收集合并 PR、按标签归类,到按模板组装、落地本地文件并完成发布前核验。读完本文,你将掌握一套可复用的、不依赖任何自动化 release-drafter 的发布说明起草方法,并理解标签体系与发布章节之间的完整映射关系。
一、技能定位:这份文档解决什么问题
generate-release-notes是 redis-py 仓库内置的一套维护者工作流技能,其唯一目标是:产出一份与项目已发布 GitHub Releases 结构一致的 Release Notes 草稿,依据是给定release branch上、自上一个发布以来的合并 PR,并按 PR 标签归类。它明确声明"Never publish it"——草稿只落地为本地 Markdown 文件,由维护者审阅后手动粘贴到 GitHub Release 界面发布。
该技能文档由三部分构成:
| 文件(仓库根目录相对路径) | 职责 |
|---|---|
| .claude/skills/generate-release-notes/SKILL.md | 入口与触发说明(skill 元信息、触发词),全文指向前述 .agents 版本 |
| .agents/skills/generate-release-notes/SKILL.md | 技能主体:目标、约束、五步工作流、核验清单 |
| .agents/skills/generate-release-notes/references/release-notes-template.md | 发布说明的章节顺序、标题、行格式与完整骨架 |
| .agents/skills/generate-release-notes/references/pr-labels-guide.md | 权威的"标签→章节"映射与无标签 PR 的推断规则 |
其中 pr-labels-guide 被文档称为authoritative, self-contained mapping(权威且自洽的映射),release-notes-template 则拥有"章节顺序、标题、行格式、完整骨架"的全部定义权。二者共同构成分类与组装的唯一事实来源。
一条硬性原则:不信任自动化 release-drafter
文档明确写道:"Do not rely on any automated release-drafter output."理由是其会漏掉 PR、且会错误归类。因此技能的每一步(收集、归类)都必须基于 git 历史手工完成,不使用任何自动生成的分类结论。这一点是整套工作流的设计哲学:宁可手工逐个确认,也不让机器猜测章节归属。
两条约束
- 只读 GitHub 访问:按仓库 owner 的既定规则,未经用户当轮明确授权,不得运行任何会产生写入的
gh或 GitHub API 调用(不创建/编辑 release、评论、标签、tag)。数据收集一律使用gh ... view/list、git log或 GET-only 的gh api/curl。文档还提示:gh在命令沙箱内可能因 TLS 错误失败,必要时需在禁用沙箱的情况下运行。 - 仅写草稿文件:技能只在工作树中写一个本地 Markdown 草稿,不 commit、不 tag、不 push、不创建 GitHub Release。
二、输入与触发方式
技能的输入不是版本号,而是release branch(发布分支)——它定义了哪些变更会被纳入本次发布说明。触发方式为自然语言关键词,包括:
release notes、create release notes、generate release notes、draft release notes、prepare release noteschangelog- 带分支/版本的请求,例如
"release notes for 8.0"表示以分支8.0作为 release-branch 输入;"generate release notes for the 8.0 branch"同理 - 询问"自上一个 tag 以来改了什么"(what changed since the last tag)
任何"release notes for X.Y.Z"形式的请求,都按"使用分支 X.Y.Z 作为发布分支"来解析。若参数中未提供分支,技能会向用户询问,绝不猜测。
三、完整工作流(五步)
步骤 1:确定发布区间与版本
- 确认发布分支存在:使用
git rev-parse --verify <branch>验证;若是远程分支(origin/<branch>)需先 fetch。每个要纳入的变更,都是"从该分支可达、且从上一个发布 tag 不可达"的提交。 - 识别上一个发布 tag:取从发布分支可达的最近一个
v*tag,命令为git describe --tags --abbrev=0 <branch>,或用只读的gh release list -L 5辅助。若用户期望不同的基准,需与其确认。 - 决定新版本号:redis-py 采用
major.minor.patch三段式(如8.0.1、7.4.1)。推断规则是:变更集中存在任何 Breaking 或 New Feature,至少是 minor 级升版;无法确定时与用户确认精确版本。tag 统一采用v<version>形式(如v8.0.2)。当前仓库主版本为 8.x(见 redis/init.py 中__version__ = "8.0.0"),这与文档中反复出现的8.0、8.0.1、8.0.0b2示例相印证。
步骤 2:收集区间内的合并 PR 与提交
列出发布分支上自上一 tag 以来的提交:
git log --oneline --no-merges <prev-tag>..<branch>被 squash/merge 的提交标题通常以
(#<pr-number>)结尾,从标题中提取 PR 号;若项目采用 merge-commit 工作流,则改用git log --merges或 GitHub compare API。对每个 PR 号,用只读命令获取其标题、标签、作者:
gh pr view <n> --json number,title,labels,author # 或 gh api repos/redis/redis-py/pulls/<n>变更行使用 PR 标题而非原始 commit subject(已发布说明采用的就是 PR 标题),二者不一致时以 PR 标题为准。
剔除任何带有
skip-changelog标签的 PR。若某提交没有关联 PR(direct push),则以 commit subject 为准,并按"无标签"处理。
步骤 3:为每个提交归类
这是整套技能的核心决策环节,依据 pr-labels-guide:
- PR 携带一个或多个分类标签时,在每一个匹配的章节下列出——一个带
deprecation+breakingchange两个标签的 PR,会同时出现在 ⚠️ Deprecations 与 🔥 Breaking Changes。 - PR没有分类标签,或只有主题/流程标签、或只有非分类仓库标签(如
bug-fix、security、techdebt)时,按 pr-labels-guide 的推断规则确定章节——所有匹配的规则都要应用,因此一个变更可能落入多个章节。同时记录你建议为这些 PR 补充的标签。 - 当分类确实存在歧义时,在草稿中留下
<!-- TODO: confirm category for #<n> -->标记并同步给用户,而不是默默猜测。
步骤 4:组装草稿
严格遵循 release-notes-template.md:
- 以
# Changes开头。 - 可选地添加
## ✨ Highlights(或一个引导性散文段落)——仅当本次发布有值得聚焦读者的重大内容时(显著新特性,或可能影响大量用户的破坏性变更);常规补丁版本不写 Highlights。 - 按模板规定的顺序输出分类章节(🚀 New Features → 🧪 Experimental → 🔥 Breaking Changes → ⚠️ Deprecations → 🐛 Bug Fixes → 🧰 Maintenance),空章节整体省略。每一行格式为
- <PR title> (#<n>)。 - 以贡献者页脚收尾:感谢语 + 去重后的
@<author>句柄列表。
步骤 5:保存为本地 Markdown 文件
- 默认路径:仓库根目录下的
release_notes/release_notes_<version>.md(如release_notes/release_notes_8.0.2.md),release_notes/目录不存在则创建,用户可指定覆盖路径。 - 不 commit、不 tag、不 push、不创建/编辑 GitHub Release——文件只是本地审阅产物,维护者手动将其内容复制进 Release 界面。若
release_notes/目录尚未加入 gitignore,需提醒维护者避免误提交。 - 文件内容即应粘贴到 Release body 的原文,不加任何额外包装或注释。
草稿写完后需向用户报告:文件路径、版本号、上一 tag、各章节提交数、被推断类别的 PR 数量及具体编号、草稿中遗留的 TODO 标记。
四、发布说明模板详解(release-notes-template.md)
章节顺序与对应标签
模板规定六个分类章节必须按下表顺序出现,并给出"哪些标签会把提交路由进该章节":
| 顺序 | 章节标题 | 路由进此章节的 PR 标签 |
|---|---|---|
| 1 | ## 🚀 New Features | feature、enhancement |
| 2 | ## 🧪 Experimental Features | experimental |
| 3 | ## 🔥 Breaking Changes | breakingchange |
| 4 | ## ⚠️ Deprecations | deprecation |
| 5 | ## 🐛 Bug Fixes | fix、bugfix、bug、BUG |
| 6 | ## 🧰 Maintenance | maintenance、dependencies、documentation、docs、testing |
配套规则:
- 空章节不渲染:没有提交的类别完全不输出(补丁版本即是如此)。
- 每行格式:
- $TITLE (#$NUMBER)——PR 标题原样,空格,括号内为 PR 号。 - 同变更 PR 合并成一行:把实现同一功能/变更的多个 PR 合并为一行,所有编号放进一个空格分隔的括号组:
- <title> (#3434 #3456 #3467),标题取最清晰者(通常是主 PR 的)。这常见于成对的 sync/async PR、跨多个 follow-up 落地的特性、或修复及其测试/类型标注 follow-up。编号按升序排列。只合并真正属于同一变更的 PR,不得为缩短列表而合并无关工作。若被合并的 PR 落入不同章节,则在每个匹配章节各放一行(同样遵守"每章节一行"规则)。 - 排除任何带
skip-changelog标签的 PR。 - 一个 PR 携带多个类别的标签时,在每个匹配章节各列一行;优先级顺序只用于"无分类标签时推断单一章节"这一场景。
- 无分类标签的提交,先按 pr-labels-guide 推断再放置。
可选手写章节
## ✨ Highlights:仅当发布有重大内容时使用(显著新特性,或影响面大的破坏性变更)。内部使用###散文小节描述每个亮点,给出代码/API 名称并链接文档或规格。常规补丁版本没有Highlights。# Changes正下方可放一段无标题的引导散文,概括头条变更并链接迁移指南(参见 8.0.0b2 预发布版)。- Highlights/引导段放在生成的分类章节之上。
贡献者页脚
以感谢语加去重后的句柄列表结尾,格式为:
We'd like to thank all the contributors who worked on this release! @handle1 @handle2 @handle3句柄以空格分隔、去重、每个被纳入 PR 的贡献者出现一次。
完整骨架
# Changes ## ✨ Highlights ### <Notable feature name> <Prose: what it is, the public API/class/option names, and links to docs or specs. Omit this whole section for routine patch releases.> ## 🚀 New Features - <PR title> (#<n>) ## 🧪 Experimental Features - <PR title> (#<n>) ## 🔥 Breaking Changes - <PR title> (#<n>) ## ⚠️ Deprecations - <PR title> (#<n>) ## 🐛 Bug Fixes - <PR title> (#<n>) ## 🧰 Maintenance - <PR title> (#<n>) We'd like to thank all the contributors who worked on this release! @handle1 @handle2已发布版本的三种实战形态
模板以三类真实发布形态收尾,可直接对照:
- Minor/Major 发布(8.0.0 风格):
# Changes→## ✨ Highlights(多个###散文小节,覆盖 async cluster pubsub、keyspace notifications、RESP3 默认开启、类型提示重载、连接/重试默认值等)→ 分类章节 → 贡献者页脚。 - 预发布(8.0.0b2 风格):
# Changes→ 关于头条破坏性变更的引导散文段(附迁移指南链接)→ New Features → Breaking Changes → Maintenance → 贡献者页脚。 - 补丁发布(8.0.1 风格):
# Changes→## 🐛 Bug Fixes→## 🧰 Maintenance→ 贡献者页脚。无 Highlights,Breaking/Experimental/New Features 等空章节整体省略。
五、PR 标签分类指南详解(pr-labels-guide.md)
分类标签(决定章节归属)
以下六类标签是唯一能将提交放入某个章节的标签:
| 章节 | 映射标签 | 何时归入此类 |
|---|---|---|
| 🚀 New Features | feature、enhancement | 新增 Redis 命令、客户端能力、公共选项,或对既有行为的用户可见增强 |
| 🧪 Experimental Features | experimental | 新增预览/实验性能力,尚不受兼容性保证覆盖(代码/测试中常同样标注experimental) |
| 🔥 Breaking Changes | breakingchange | 变更或移除任何公共契约:函数/方法签名、参数名、默认值、返回类型、抛出的异常类型、线协议/响应形状、持久化或连接配置——任何可能破坏从最新发布版升级的用户的内容 |
| ⚠️ Deprecations | deprecation | 将公共 API/选项/行为标记为弃用,但本版本仍保持可用(通常发出DeprecationWarning);若同一 PR 还移除/变更了另一公共契约,则同时列入 🔥 Breaking Changes |
| 🐛 Bug Fixes | fix、bugfix、bug、BUG | 修正受支持功能中的错误行为、崩溃、泄漏或回归 |
| 🧰 Maintenance | maintenance、dependencies、documentation、docs、testing | CI/发布工具、依赖升级、文档、测试、重构、类型标注/lint 清理——无用户可见行为变化 |
多类别标签的 PR 在每个匹配章节各出现一次;表内优先级顺序仅用于无标签时的单一章节推断。
需要显式决策的仓库标签
以下标签存在于 redis-py 仓库,但不属于上述分类标签,仅带这些标签的 PR 不会自报章节:
bug-fix—— 视为 🐛 Bug Fixes(bug/fix的同义词;建议同时补打bug)。security—— 默认归入 🐛 Bug Fixes;若修复改变了公共契约则改为 🔥 Breaking Changes。无论归入何处,都强烈建议在## ✨ Highlights中连同 advisory/CVE 引用一起点名。techdebt—— 🧰 Maintenance。deprecation—— 路由到 ⚠️ Deprecations;若本版本内就移除/变更了公共契约(不只是警告),则归入 🔥 Breaking Changes。- 主题/领域标签(
async、cluster、windows、redis-7、redis-py-5、RediSearch、RedisJSON、RedisGraph)——只描述变更作用于哪里,不描述是什么类型,永远不直接决定章节;仅带这些标签的 PR 仍需按下方规则做类别决策。
排除与流程标签
skip-changelog——从发布说明中完全排除该 PR。- 流程/分诊类标签永远不会出现在发布说明中,也不参与分类:
triage、question、discussion、duplicate、stale、help-wanted、good first issue、need more info、needs-information、ready-for-merge、changes-requested、waiting-for-response、docs-review、update-docs、run-benchmark、hacktoberfest-accepted、tracking-issue。
无标签时的推断规则
无分类标签时,从变更本身推断章节,每条匹配规则都要应用(一个变更可同时落入多个章节,例如既弃用一个 API 又破坏另一个,则同时出现在 Deprecations 与 Breaking Changes):
- New Features—— 新增 Redis 命令、客户端/连接能力、公共选项,或明显用户可见的增强;标题常以
feat/feature/add开头。建议标签:feature。 - Experimental Features—— 明确为预览/实验性能力(代码中标记 experimental、测试位于 experimental 标记下,或声明为 preview)。建议标签:
experimental。 - Breaking Changes—— diff 相对最新发布版变更/移除了公共签名、参数名、默认值、返回类型、抛出的异常类型或线协议/响应形状;或 PR 标题/正文出现 "breaking"、"remove"、"drop support"。建议标签:
breakingchange。 - Deprecations—— 标记公共 API/选项/行为为弃用但本版本保持可用(如添加
DeprecationWarning、docstring 中注明 "deprecated"、或@deprecated标记),本版本不删除。建议标签:deprecation。 - Bug Fixes—— 修复错误行为、崩溃、连接/资源泄漏或回归;标题常以
fix开头,分支名为bug-*。建议标签:bug。 - Maintenance—— 其余一切无用户可见行为变化的变更:只涉及
*.md、.github/*、docs/、tests/、pyproject.toml/dev_requirements.txt/docker-compose.yml/dockers//tasks.py、依赖升级、重构、类型标注/lint 清理或 CI;分支名为maintenance-*。建议标签:maintenance。
分支命名提示:bug-*→ Bug Fixes;maintenance-*→ Maintenance;feature-*→ New Features;只改动*.md或.github/*→ Maintenance。
当分类确实模糊时,在草稿中留下<!-- TODO: confirm category for #N -->注释记录不确定性,而不是默默猜测,并同步给用户以便给 PR 补上正确标签。
sync/async 配对 PR 的特殊处理
redis-py 同时维护同步栈(redis/)与异步栈(redis/asyncio/)两条平行实现,一个行为变更经常以成对的 sync/async 工作交付(通常合并在单个 PR 内)。若两个独立 PR(一个 sync、一个 async)实现了同一变更,则按同一变更处理:在相同章节合并为一行,两个 PR 号放入同一个括号组(- <title> (#3434 #3456)),遵循前述分组规则。这一点也与仓库的双栈结构(redis/ 与 redis/asyncio/、测试镜像于 tests/ 与 tests/test_asyncio/)相互印证。
六、核验与发布前检查
技能文档在生成后要求执行以下核验,确保草稿与 git 历史严格对账:
- 提交数对账:所有变更行中引用的去重 PR 号(合并行贡献其全部编号)加上被排除的
skip-changelogPR,应等于git log <prev-tag>..<branch>中的提交数(减去 merge 提交)。合并相关 PR 会减少行数但不会减少 PR 引用数,因此按 PR 号对账,而非按行数。 - 章节核验:章节顺序与标题严格匹配 release-notes-template.md,且没有输出空章节。
- 引用核验:每个被纳入的 PR 号都能解析到真实 PR,每个贡献者句柄只出现一次。
- 格式抽检:与上一个已发布 release 的排版对照(
gh release view <prev-tag>,只读)。
七、仓库相关文件速查
以下是本工作流涉及的全部仓库文件(均为仓库根目录相对路径),可进一步深入研读:
- .claude/skills/generate-release-notes/SKILL.md —— 技能入口、触发词与元信息
- .agents/skills/generate-release-notes/SKILL.md —— 技能主体(目标、约束、五步工作流、核验清单)
- .agents/skills/generate-release-notes/references/release-notes-template.md —— 章节顺序、行格式、完整骨架与实战样例
- .agents/skills/generate-release-notes/references/pr-labels-guide.md —— 标签→章节权威映射与推断规则
- CHANGES —— 4.0.0 之前的变更历史;4.0.0 之后变更全部追踪于 GitHub Releases
- redis/init.py —— 当前版本定义(
__version__ = "8.0.0"),用于对照文档示例中的 8.x 发布形态 - redis/ 与 redis/asyncio/ —— sync/async 双栈实现,对应分类指南中的 sync/async 配对处理
【免费下载链接】redis-pyRedis Python client项目地址: https://gitcode.com/GitHub_Trending/re/redis-py
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考