news 2026/10/1 16:51:40

go-redis 版本发布准备全流程:从 version.go 到 RELEASE-NOTES.md 的本地构建指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
go-redis 版本发布准备全流程:从 version.go 到 RELEASE-NOTES.md 的本地构建指南
  • 后端
  • 数据库客户端
  • 缓存

【免费下载链接】go-redis

Redis Go client

项目地址:https://gitcode.com/GitHub_Trending/go/go-redis
点击查看免费下载

版本发布是开源项目最需要纪律的环节之一。本文基于 go-redis 仓库中内置的prepare-release技能文档,系统讲解在本地完整准备一次 go-redis(vX.Y.Z)发布的六步流程:确定下一个语义化版本、收集自上次发布以来的变更、编写RELEASE-NOTES.md条目、通过 scripts/release.sh 提升版本、用 scripts/tag.sh 的 dry-run 模式验证,最后将发布步骤交接给维护者。读完本文,你将掌握 go-redis 官方发布流程的完整操作手册,以及每个命令背后仓库脚本的真实校验逻辑。

核心原则:准备一切,但绝不发布

go-redis 的发布流程刻意将「准备」与「发布」分离。prepare-release技能的边界非常明确:

  • 绝不运行scripts/tag.sh ... -t—— 该-t标志会真正创建并推送 git tag;
  • 绝不执行git push(既不推 commit 也不推 tag);
  • 绝不在维护者明确要求之前代替他们提交 commit。

整个流程的交付物是一份可审阅的 diff:提升后的版本号加上一段新的RELEASE-NOTES.md条目。所有「真正对外生效」的动作——提交、合并 PR、打 tag、推送——都由人类维护者审阅后手动完成。

这种设计把「人为失误风险最高的写操作」隔离在自动化脚本之外:脚本只负责可重复、可校验的文本改写(版本号、go.mod 依赖),而不可逆的网络写操作保留给人工确认。这也正是为什么后面的每个步骤都反复出现「dry-run」「不 commit」「不 push」的约束。

第一步:选择下一个版本号(语义化版本)

版本的唯一事实来源是仓库根目录的 version.go。当前仓库中该文件的内容为:

package redis // Version is the current release version. func Version() string { return "9.23.0-beta.1" }

用一条 grep 即可确认当前版本:

grep 'return' version.go # e.g. return "9.21.0"

下一步是依据自上次发布以来合入的变更,按语义化版本(semver)规则确定下一个vX.Y.Z:

  • patch(Z 位)—— 仅含 bug 修复,是零成本的 drop-in 升级;
  • minor(Y 位)—— 包含新特性,但无破坏性变更,同样是 drop-in 升级;
  • major(X 位)—— 存在破坏性变更。

如果变更集的性质有歧义(例如既有新特性又疑似破坏性改动),应与维护者确认再决定版本级别,而不是自行猜测。从仓库现状看,version.go 中的版本为9.23.0-beta.1,是一个带预发布后缀(-beta.1)的版本,这也提示读者:go-redis 的 tag 体系是支持语义化版本预发布/构建元数据后缀的(见后文 scripts/release.sh 的 TAG 正则校验)。

第二步:定位上次发布并收集变更

go-redis 是一个多模块仓库(monorepo with submodules)。关键陷阱在于:scripts/tag.sh 会为每一个公共子模块单独打 tag,例如extra/redisotel/v9.21.0、extra/redisprometheus/v9.21.0等。因此,一个朴素的git describe很可能返回的是子模块 tag 而不是根模块 tag。必须显式匹配「根 tag」——即只匹配以v开头且紧跟数字的 tag:

LAST=$(git describe --tags --abbrev=0 --match 'v[0-9]*') # e.g. v9.21.0 git log "$LAST"..HEAD --oneline gh pr list --state merged --limit 100 \ --json number,title,author,mergedAt,url --search "merged:>=<last-release-date>"

--match 'v[0-9]*'之所以能避开子模块 tag,是因为子模块 tag 形如extra/redisotel/vX.Y.Z,其前缀是目录名而非v加数字。git log "$LAST"..HEAD给出上次发布之后的全部提交;gh pr list则拉取自上次发布日期以来合入的 PR 清单(含编号、标题、作者、合入时间与 URL),用于编写 release notes。

拿到 PR 清单后,需要将其分类到后续 release notes 的各小节中:

  • highlights—— 对用户影响最大的变更;
  • new features—— 新特性;
  • bug fixes—— bug 修复;
  • performance—— 性能改进;
  • testing/infrastructure—— 测试与基础设施。

同时要执行严格的排除规则:dependabot 依赖升级、仅改 typo 的文档修复、对用户无可见影响的内部重构,都应从 release notes 中剔除;dependabot[bot]也不能出现在贡献者名单中。这些排除项与.github/RELEASE_NOTES_TEMPLATE.md中「What to Exclude」一节完全一致(详见下文第三步)。

第三步:编写 RELEASE-NOTES.md 条目

追加位置与模板

在 RELEASE-NOTES.md 的顶部插入新的# X.Y.Z (YYYY-MM-DD)小节(新版本在最上方,旧条目保持不动)。格式必须严格遵循 .github/RELEASE_NOTES_TEMPLATE.md(注意该文件位于仓库根目录的.github/下,不是 skill 文档所在目录):

  • 固定的小节顺序:🚀 Highlights→✨ New Features→🐛 Bug Fixes→⚡ Performance→🧪 Testing & Infrastructure→👥 Contributors;
  • 每个条目使用(#PR) by @user的 PR 与贡献者链接格式;
  • 结尾必须包含**Full Changelog**对比链接,形如${LAST}...vX.Y.Z(即上次发布与本次发布的 tag 对比);
  • 首行(lead line)要说明发布类型以及是否属于 drop-in upgrade,并与既有条目保持一致的措辞风格。

仓库中 RELEASE-NOTES.md 的当前最新条目即是一个可直接对照的实例,例如# 9.23.0-beta.1 (2026-09-11)开头写「This is abetarelease. You can upgrade without changes to your code.」,随后是 Highlights、New Features、Bug Fixes、Performance、Testing & Infrastructure 与 Contributors 各节。

模板本身还携带了完整的「应排除内容」与格式细则,技能文档明确要求读取模板而不是重新发明规则——模板里还给出了获取 PR 信息的推荐方式(gh pr list --state merged --limit 50 --json number,title,author,mergedAt,url)以及一条「识别 3-5 个最重要的变更作为 Highlights」的工作流建议。

RELEASE-NOTES.md 与 release-drafter 的分工

仓库中存在两套 release 记录机制,职责不同:

  • RELEASE-NOTES.md是人工精修(curated)的发布记录,是发布准备流程中唯一需要编辑的文件;
  • .github/release-drafter-config.yml驱动 GitHub 的 release-drafter 工具,按 PR 标签自动草拟一份 GitHub Release。该配置定义了autolabeler(如 bug 分支打bug标签、feature 分支打feature标签)、类别映射(Breaking Changes / Experimental Features / New Features / Bug Fixes / Maintenance)以及exclude-labels: skip-changelog、exclude-contributors: dependabot等排除规则;
  • .github/workflows/release-drafter.yml在每次 push 到master分支时触发release-drafter/release-drafter@v7action,引用上述配置文件自动更新草稿。

也就是说:自动草稿可以快速生成,但最终对外发布的手写精修记录是RELEASE-NOTES.md。编写时不要被自动草稿带偏,以模板和人工整理为准。

第四步:提升版本号(运行 release.sh)

编写好 release notes 后,运行仓库自带的版本提升脚本:

TAG=vX.Y.Z ./scripts/release.sh

scripts/release.sh 的实际行为可以从源码确认,它做三件事:

  1. 校验 TAG:TAG环境变量必填;随后用正则^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$校验格式(支持预发布后缀-beta.1与构建元数据+...);再通过git tag --list ${TAG}检查该 tag 是否已存在,存在则直接退出。
  2. 批量更新所有子模块的 go.mod:脚本用find . -mindepth 2 -type f -name 'go.mod'找出全部子模块(如extra/redisotel、example/autopipeline等),对每个go.mod用 sed 把其中github.com/redis/go-redis...相关依赖的版本号统一替换为新 TAG,随后在子模块目录内执行go mod tidy -compat=1.24。
  3. 更新 version.go:用 sed 把return "旧版本"改写为return "新版本"(注意去掉 TAG 的前导v)。

脚本结尾会打印Done. Review changes with 'git diff' and commit when ready.,并明确不 commit、不 push、不切换分支。你可以对照 extra/redisotel/go.mod 看到替换后的真实形态:require中同时出现github.com/redis/go-redis/extra/rediscmd/v9 v9.23.0-beta.1与github.com/redis/go-redis/v9 v9.23.0-beta.1,且保留指向仓库根目录的replace github.com/redis/go-redis/v9 => ../..本地替换指令。

顺带一提,仓库还提供 scripts/bump_deps.sh,其职责不同:它在每个子模块内执行go get -d && go mod tidy,用于日常同步依赖,而不是发布版本号,注意不要混淆。

第五步:验证(仅 dry-run)

版本提升完成后,运行 scripts/tag.sh 的dry-run模式做发布前检查。该脚本默认就是 dry-run(DRY_RUN=1),只有显式传入-t才会真正执行 git 命令:

./scripts/tag.sh vX.Y.Z # DRY RUN — must pass cleanly; never add -t here make build git diff --stat # review version.go, submodule go.mod, RELEASE-NOTES.md

从 scripts/tag.sh 源码看,dry-run 阶段会执行两类硬校验:

  • version.go 校验:用grep -Fq "\"${TAG#v}\"" version.go检查version.go是否已包含去掉v前缀的目标版本,不匹配则报错退出;
  • 所有 go.mod 校验:遍历仓库内每一个go.mod,用 awk 解析require块中所有github.com/redis/go-redis开头的依赖,逐一比对版本号是否等于${TAG},任何不一致都会计数并最终exit 1。

校验通过后,脚本计算需要打 tag 的公共包目录(PACKAGE_DIRS,用grep -E -v "example|internal"显式排除 example 与 internal 目录),然后以 dry-run 方式逐条打印「DRY-RUN: Would execute: git tag ...」与「DRY-RUN: Would execute: git push origin ...」,覆盖根 tag 以及每个公共子模块 tag(如extra/redisotel/vX.Y.Z)。

随后运行make build(Makefile 中的build目标执行go build .)确认工程可编译,最后用git diff --stat审阅改动面:应恰好覆盖 version.go、各子模块go.mod与 RELEASE-NOTES.md。dry-run 指出的任何问题都要在交接前修复。

第六步:交接给维护者

技能在完成上述全部准备(即第五步)后停止,并向维护者报告「发布已暂存(staged)」以及剩余的发布步骤清单,由维护者亲自执行:

  1. 审阅git diff,然后提交,提交信息形如chore(release): vX.Y.Z(遵循仓库的 commit-style 约定,且不带 AI-attribution 尾注);
  2. 打开并合并发布 PR;
  3. 合并后打 tag 并推送:./scripts/tag.sh vX.Y.Z -t(此刻才动用-t标志);
  4. release-drafter会自动发布 GitHub Release,如有必要再与RELEASE-NOTES.md条目对账。

这四步中的每一步都属于「发布(publish)」范畴,全部留给人类维护者;prepare-release的边界就是停在第五步之后,不 commit、不 tag、不 push。

仓库中的发布支撑设施一览

整个发布流程依赖仓库内以下几处真实文件,供读者深入核对:

用途文件说明
版本唯一事实来源version.goVersion()返回当前版本,当前为9.23.0-beta.1
版本提升脚本scripts/release.sh校验 TAG、批量更新子模块 go.mod 并go mod tidy、更新 version.go
打 tag 脚本scripts/tag.sh默认 dry-run;校验 version.go 与全部 go.mod;-t才真正执行
发布记录RELEASE-NOTES.md人工精修、最新条目在最上方
发布模板.github/RELEASE_NOTES_TEMPLATE.md小节顺序、链接格式、排除规则、Full Changelog
自动草稿配置.github/release-drafter-config.yml按 PR 标签自动生成 GitHub Release 草稿
自动草稿工作流.github/workflows/release-drafter.ymlpush 到 master 时触发 release-drafter
构建目标Makefilemake build用于发布前编译验证
子模块依赖示例extra/redisotel/go.mod展示 go-redis 依赖版本被统一改写后的形态

总结:一条可复核、可回退的发布前检查链

go-redis 的发布准备流程可以概括为一条「事事可校验」的链条:version.go是版本事实源 →git describe --match 'v[0-9]*'精确锁定根 tag → 模板约束 release notes 格式 →release.sh以正则与 tag 冲突检查守护版本改写 →tag.shdry-run 复核 version.go 与每个子模块 go.mod →make build保证可编译 → 人工审阅 diff 后交接。整个过程中所有自动化脚本都刻意不触碰「推送」这类不可逆操作,把发布权牢牢留在维护者手中——这正是大型开源客户端库把流程纪律内建到工具链中的典型做法。如果你需要维护自己的多模块 Go 项目,这套「准备与发布分离 + dry-run 校验 + 人工交接」的模式同样值得直接借鉴。

  • 后端
  • 数据库客户端
  • 缓存

【免费下载链接】go-redis

Redis Go client

项目地址:https://gitcode.com/GitHub_Trending/go/go-redis
点击查看免费下载
上一篇:C语言单元测试框架终极比较指南:从gumbo-parser学习最佳实践
下一篇:Bili.Uwp与官方客户端对比:功能与性能深度测评

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 16:50:25

VSCode+Xdebug+phpstudy PHP调试环境配置与断点排查实战

PHP代码调试&#xff08;vscodexdebugphpstudy&#xff09;这套组合&#xff0c;我前前后后用了五六年&#xff0c;也帮不少同事搭过环境。今天把这套东西从头到尾捋一遍&#xff0c;包括版本怎么配、php.ini里到底该写什么、launch.json那些参数都是干什么的&#xff0c;以及我…

作者头像 李华
网站建设 2026/10/1 16:49:49

5 类免费云服务实测:不花一分钱搭齐开发环境

5 类免费云服务实测&#xff1a;不花一分钱搭齐开发环境 【免费下载链接】free-for-dev A list of SaaS, PaaS and IaaS offerings that have free tiers of interest to devops and infradev 项目地址: https://gitcode.com/GitHub_Trending/fr/free-for-dev 上周有同事…

作者头像 李华
网站建设 2026/10/1 16:49:06

一人企业方法论V2.1学术研究:个体创业者的终极成功指南

一人企业方法论V2.1学术研究&#xff1a;个体创业者的终极成功指南 一人企业方法论是基于作者多年实践经验的深度理论研究成果&#xff0c;为个体创业者提供了一套完整的思维框架和实践路径。这套方法论不仅适用于独立开发者&#xff0c;也适合自媒体、电商、数字商品创作等各…

作者头像 李华
网站建设 2026/10/1 16:48:59

《一人企业方法论》V2.1商业授权:企业培训的合作模式

《一人企业方法论》V2.1商业授权&#xff1a;企业培训的合作模式 你还在为团队缺乏系统化的轻资产创业方法论而烦恼吗&#xff1f;想快速提升员工副业创收能力却找不到合适教材&#xff1f;本文将详解《一人企业方法论》V2.1的商业授权体系&#xff0c;帮助企业通过标准化培训…

作者头像 李华
网站建设 2026/10/1 16:47:39

白盒测试实战指南:从控制流图到覆盖率验证

1. 这份模板不是“交作业的填空纸”&#xff0c;而是你第一次真正理解白盒测试逻辑的起点“白盒测试实验报告模板”——光看标题&#xff0c;很多人第一反应是&#xff1a;又一个要抄的格式文档&#xff0c;凑够页数、画几个流程图、贴几段代码截图就完事。但我在广工带过三届软…

作者头像 李华