十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Go 版本发布说明(Release Notes)工作流:从 doc/next 片段到发布文档的完整指南

Go 版本发布说明(Release Notes)工作流:从 doc/next 片段到发布文档的完整指南 Go 版本发布说明Release Notes工作流从 doc/next 片段到发布文档的完整指南【免费下载链接】goThe Go programming language项目地址: https://gitcode.com/GitHub_Trending/go/go本文基于 Go 官方仓库中的 doc/README.md 展开讲解 Go 项目如何组织、撰写和生成每个版本的发布说明doc/initial与doc/next两级目录的分工、开发者如何为变更提交CL补充发布说明片段、api/nextAPI 变更文件与说明片段的强制对应关系、发布说明的 Markdown 书写规范以及发布团队如何用relnote工具完成合并与生成。读完本文你能够独立完成一次标准的发布说明编写流程并理解 Go 发布文档从“碎片化片段”到“单一发布文档”的自动化管线。doc 目录的发布说明体系initial 与 next 的分工doc/README.md 开篇指出doc目录下的initial与next两个子目录专门用于存放发布说明release notesdoc/initial保存的是模板骨架。例如 doc/initial/1-intro.md 的标题写作 “DRAFT RELEASE NOTES — Introduction to Go 1.N”并带有占位符 “{Month} {Year}”表示这是一个尚未填充版本信息的初始模板doc/next保存的是当前开发周期正在累积的发布说明。当前仓库中 doc/next/1-intro.md 的标题为 “DRAFT RELEASE NOTES — Introduction to Go 1.28”并声明 “Go 1.28 is not yet released … expected to be released in February 2027”说明本仓库正处于 Go 1.28 的开发周期。next目录的顶层文件采用数字-主题.md的命名方式当前包括文件对应章节1-intro.md版本简介2-language.md语言变更3-tools.md工具变更4-runtime.md运行时变更5-toolchain.md工具链变更6-stdlib/标准库变更目录见下文7-ports.md平台移植这种命名并非随意doc/README.md 说明开发周期结束时这些文件会**按文件路径名的排序顺序拼接concatenated in sorted order by pathname**合并为最终文档。数字前缀正是为了保证拼接后章节顺序稳定、可预期——这是理解整个发布说明体系的第一个关键机制。开发者规则发布说明必须写入 next而不是注释doc/README.md 对开发者的第一条硬性规定是Do not add RELNOTEyes comments in CLs.Instead, add a file to the CL (or ask the author to do so).也就是说Go 项目放弃了早期“在代码注释里标记RELNOTEyes、由机器人代为补写说明”的做法改为由提交者在 CL 中直接附带或要求作者附带一个说明文件。这使发布说明与代码变更在同一个变更中原子地落地避免了说明滞后或缺失。stdlib 变更的特殊目录*stdlib/*minor并非所有说明文件都放在顶层。doc/README.md 规定匹配*stdlib/*minor这个 glob 的目录中的文件会被特殊处理——文件必须放在与标准库包路径对应的子目录中这些包路径的标题headings会自动生成撰写者无需手写。当前 doc/next/6-stdlib/99-minor/ 目录是这一规则的活样本其结构完整镜像了标准库的包树doc/next/6-stdlib/99-minor/ ├── 0-heading.md # 自动生成的标题锚点 ├── README # 目录用途说明 ├── embed/80822.md ├── encoding/base32/20235.md ├── encoding/base64/20235.md ├── flag/65675.md ├── go/parser/79802.md ├── net/29678.md ├── net/http/79040.md ├── net/http/79656.md ├── net/http/80058.md ├── net/http/url/79946.md ├── syscall/68595.md └── testing/fstest/80822.md testing/synctest/77320.md其中 doc/next/6-stdlib/99-minor/README 一句话点明该目录的定位“API changes and other small changes to the standard library go here.”标准库的 API 变更和其他小型变更写在这里。标题自动生成的实现细节体现在两个0-heading.md文件中doc/next/6-stdlib/0-heading.md 提供章节级标题## Standard library {#library}doc/next/6-stdlib/99-minor/0-heading.md 提供小节标题### Minor changes to the library {#minor_library_changes}末尾的{#anchor}是供自动生成的包路径标题做锚点链接用的。文件名 提案/问题编号观察上面的文件名80822、20235、65675、79040……可以发现文件名就是 API 提案或 issue 的编号这直接服务于下一条规则。api/next 与 doc/next 的强制对应关系doc/README.md 给出了本项目发布说明体系中最严格的一条规则Files in this reposapi/nextdirectory must have corresponding files indoc/next/*stdlib/*minor. The files should be in the subdirectory for the package with the new API, and should be named after the issue number of the API proposal.即api/next中的每个 API 变更文件都必须在doc/next的 stdlib minor 目录下有对应的说明文件对应文件放在新增 API 所在包的子目录下并以提案 issue 编号命名。README 中给的例子是若存在6-stdlib/99-minor目录则api/next中的pkg net/http, function F #12345必须对应一个doc/next/6-stdlib/99-minor/net/http/12345.md。该文件至少要包含一个完整句子或一个 TODO理想情况下注明负责补全说明的人。当前仓库里就有完全符合这一规则的成对实例。api/next/65675.txt 的内容为pkg flag, func All() iter.Seq[*Flag] #65675 pkg flag, method (*FlagSet) All() iter.Seq[*Flag] #65675 pkg flag, type Flag struct, IsSet bool #65675它对应 doc/next/6-stdlib/99-minor/flag/65675.mdThe new [FlagSet.All] method returns an iterator over all the flags in the FlagSet; the function [All] does the same for the global [CommandLine] flag set. The new [Flag.IsSet] field indicates whether the flag has been set.可以看到三行pkg flag …API 描述与一个flag/65675.md说明片段一一对应而说明片段使用的正是下面一节介绍的符号链接写法[FlagSet.All]、[All]、[Flag.IsSet]。这条规则有自动化测试兜底对应关系并非仅靠约定仓库内有专门的检查代码。src/cmd/relnote/relnote_test.go 中的TestCheckAPIFragmentssrc/cmd/relnote/relnote_test.go#L21-L39会遍历api/next/*.txt中所有文件调用relnote.CheckAPIFile(rootFS, apiFile, docFS, doc/next)逐一验证每个 API 文件在doc/next下存在对应说明片段// Check that each file in api/next has corresponding release note files in doc/next. func TestCheckAPIFragments(t *testing.T) { ... files, err : fs.Glob(rootFS, api/next/*.txt) ... for _, apiFile : range files { if err : relnote.CheckAPIFile(rootFS, apiFile, docFS, doc/next); err ! nil { t.Errorf(%s: %v, apiFile, err) } } }从源码结构看该检查以-check标志启用见 src/cmd/relnote/relnote_test.go#L18依赖外部包golang.org/x/build/relnote提供的CheckAPIFile函数完成实际校验。这意味着开发者如果提交了api/next文件却忘记附doc/next片段检查会直接报错——README 中的对应关系要求是机器可执行的。关联提案/issue/NUMBER 写法与自动 TODO 标记doc/README.md 还规定如果你的 CL 实现的是一个已被接受的提案accepted proposal必须在发布说明中以/issue/NUMBER的形式提及提案的 issue 编号渲染后会在文本中生成指向该 issue 的链接。如果不想在正文中出现该编号可以改为 HTML 注释形式!-- go.dev/issue/12345 --同时doc/README.md 提醒如果某个已被接受的提案被 CL 提及却没有出现在发布说明中自动化工具会将其标记为 TODO——即使该提案只是新增 API 也不例外。这与上一节的relnote工具链见“发布团队流程”相呼应未完成的说明工作会在周期收尾前被系统性揪出来。发布说明的 Markdown 书写规范doc/README.md 给出了一套在发布说明 Markdown 中可用的链接/引用形式[http.Request] # symbol documentation; auto-linked as in Go doc strings [Request] # short form, for symbols in the package being documented [net/http] # package link #12345 # GitHub issues CL 6789 # Gerrit changelists逐条解读形式含义[http.Request]符号文档链接自动生成行为与 Go doc 注释中的自动链接一致[Request]短形式用于指代“正在被说明的那个包”内部的符号[net/http]包链接#12345issue 链接CL 6789Gerrit 变更列表changelist链接实际片段中这套写法随处可见。例如 doc/next/6-stdlib/99-minor/net/http/79040.md 写道The long-deprecated [Transport.CancelRequest] now does nothing. Use [NewRequestWithContext] (available since Go 1.13) to create a cancellable request.[Transport.CancelRequest] 与 [NewRequestWithContext] 都会按 Go doc 字符串的规则自动链接到对应的符号文档而 doc/next/6-stdlib/99-minor/testing/synctest/77320.md 则用[testing.(*T).Run]这种限定形式引用了其他包中的方法。注意这些链接在next阶段只是纯文本标记由合并/生成阶段解析为真实文档链接。本地预览在本地站点查看合并后的 next 内容doc/README.md 提供了在本地预览“合并后”效果的命令。在仓库根目录下运行go run golang.org/x/website/cmd/golangorglatest -goroot..然后访问http://localhost:6060/doc/next编辑文件后刷新页面即可看到最新效果。这里-goroot..指向 Go 源码仓库根目录本地站点工具会直接读取doc/next下全部片段按前文所述的排序规则拼接并渲染出完整的草稿文档——相当于在不触发正式发布流程的情况下提前看到relnote generate的产物。发布团队流程relnote 工具的三步工作流doc/README.md 的“For the release team”一节描述了周期收尾阶段的操作核心工具是relnote位于外部仓库golang.org/x/build/cmd/relnote它直接操作doc/next中的文件收尾前检查运行relnote todo列出所有未完成的发布说明工作即上文提到的被自动标记的 TODO包括缺失的说明片段、未提及的已接受提案等生成发布文档运行relnote generate将next中所有.md文件合并为单一文件随后尽量原子地完成两件事——把生成的文件加入 website 仓库的_content/doc目录同时删除本仓库的doc/next目录开启下一个周期用initial的内容填充新的next。在仓库根目录下 cd doc cp -R initial/ next然后编辑next/1-intro.md把其中的 “Go 1.N / {Month} {Year}” 占位符改为下一版本号与发布日期。这正好解释了initial目录的存在意义它是每个周期next的初始快照。以当前周期为例initial/1-intro.md中的 “Go 1.N … {Month} {Year}” 占位符在 Go 1.28 周期中被替换成了具体的 “Go 1.28 … February 2027”见 doc/next/1-intro.md印证了第 3 步的实际执行结果。小结一次完整的发布说明生命周期把 doc/README.md 的规则与仓库现状结合一次发布说明的完整生命周期是周期开始cp -R initial/ next更新next/1-intro.md的版本号与日期日常开发每个 CL 按归属写入next对应位置——语言/工具/运行时变更进顶层编号文件标准库小型变更与 API 变更进6-stdlib/99-minor/包路径/issue号.md若 CL 触碰了api/next如 api/next/77320.txt 中pkg testing/synctest, func Subtest(*testing.T, string, func(*testing.T)) #77320必须有同名编号的说明片段如 doc/next/6-stdlib/99-minor/testing/synctest/77320.md且 TestCheckAPIFragments 会持续保证这一约束书写规范使用符号自动链接、/issue/NUMBER、issue 与 CL 链接等固定形式让说明在生成阶段能正确链接到文档与提案周期收尾relnote todo清理欠账 →relnote generate合并 → 产物进入 website 仓库doc/next归档移除本地验证随时可用本地网站实例在localhost:6060/doc/next预览合并效果。整个体系的设计要点在于以文件路径为唯一事实来源——排序决定章节顺序目录镜像决定包标题文件名决定 API 关联配合自动化检查CheckAPIFile与生成工具relnote把“发布说明”从人为维护的文档变成了可校验、可合并、可重复执行的工程化流程。【免费下载链接】goThe Go programming language项目地址: https://gitcode.com/GitHub_Trending/go/go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表