ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OpenTelemetry Go 多模块版本发布流程深度指南:从 semconv 升级、模块集打 tag 到 GPG 签名

OpenTelemetry Go 多模块版本发布流程深度指南:从 semconv 升级、模块集打 tag 到 GPG 签名 OpenTelemetry Go 多模块版本发布流程深度指南从 semconv 升级、模块集打 tag 到 GPG 签名【免费下载链接】kubernetesProduction-Grade Container Scheduling and Management项目地址: https://gitcode.com/GitHub_Trending/kuber/kubernetes本文以当前仓库 vendored 的go.opentelemetry.io/otel模块位于 vendor/go.opentelemetry.io/otel自带的发布流程文档 vendor/go.opentelemetry.io/otel/RELEASING.md 为主体完整讲解其官方版本发布全流程如何升级并重新生成 Semantic Conventions 代码、如何用multimod工具对多个 module set 统一改版本、如何校验 API 兼容性、如何给数十个 Go 子模块打 tag、如何按 CNCF 规范签名发布产物并维护里程碑。读懂本指南后你将掌握一套可用于任何 Go 多模块仓库的、可复现的版本发布 SOP。背景说明opentelemetry-go是 Kubernetes 通过 Go module 机制 vendored 的第三方遥测依赖其整棵仓库源码连同Makefile、versions.yaml、CHANGELOG.md都原样保留在vendor/go.opentelemetry.io/otel/下。因此本文中所有命令、Makefile 目标与配置均可在该目录中直接核对。一、发布总览与整体节奏一次完整的 OpenTelemetry Go 发布按以下阶段推进每个阶段都有对应的 Makefile 目标或人工操作创建Version Release跟踪 issue若有新的语义约定Semantic Conventions上游 tag则执行Semantic Convention Upgrade生成新semconv子包、替换全库 import执行Breaking changes validationmake gorelease与contrib 仓库兼容性验证进入Pre-Release在versions.yaml中决定发布哪些 module set 与版本号用make prerelease生成改动分支更新 Changelog 并提 PR 合入执行Tag用make add-tags给主模块与所有子模块打 tag 并推送下载归档并做GPG 签名CNCF 合规要求在 GitHub 创建Release归档不可后补执行Post-Release发布 contrib、更新官网文档、收尾里程碑并关闭 issue。从该目录的 Makefile 可以看到发布相关的工具统一由internal/tools子模块构建到.tools/下MULTIMOD $(TOOLS)/multimod来自go.opentelemetry.io/build-tools/multimod、GORELEASE来自golang.org/x/exp/cmd/gorelease、SEMCONVKIT来自本仓库internal/tools/semconvkit——这正是下述各make目标背后真正的执行者。二、发布前置创建Version Releaseissue第一步是创建一个Version Release类型的 issue用其 todo 列表跟踪整个发布过程从 semconv 升级到打 tag、签名、收尾里程碑每完成一项勾选一项最终发布完成后关闭该 issue见文档原句与下文关闭 issue环节。三、Semantic Convention 升级升级前最易出错的环节OpenTelemetry 的语义约定HTTP、DB、Messaging 等跨语言共享的 attribute 定义由独立的上游仓库发布新版本。上游每发一版就意味着本仓库需要生成新版本的semconv代码包。3.1 用semconv-generate生成新版本子包文档给出的标准流程是先设置TAG环境变量为要生成的语义约定版本号再执行make semconv-generateexport TAGv1.30.0 # 换成你要生成的版本号 make semconv-generate # 使用导出的 TAG命令执行后会在semconv目录下产生一个新的版本子包。对照 Makefile 可看到该目标实际做了什么从 dependencies.Dockerfile 中解析出weaver镜像WEAVER_IMAGE强制要求TAG非空否则报错退出创建semconv/TAG目录然后以 Docker bind mount 方式把本仓库的semconv/templates与新建的TAG目录挂进容器从https://github.com/open-telemetry/semantic-conventions/archive/refs/tags/$(TAG).zip拉取上游约定模型用registry generate产出 Go 代码最后用semconvkit工具对产物做校验与整理。当前 vendored 快照中 semconv 目录下已存在v1.37.0、v1.40.0、v1.41.0三个版本子包每个子包都包含attribute_group.go、error_type.go、exception.go、schema.go以及独立的httpconv、otelconv转换包——这就是多次执行上述流程留下的历史产物。3.2 更新 CHANGELOG 并提交新增包生成完新子包后需要向仓库提交 PR 合入并同步更新CHANGELOG.md追加一条符合下述格式的记录把NEW VERSION、PREVIOUS VERSION、#PR_NUMBER替换为实际值见 CHANGELOG.md 的Added章节惯例- The go.opentelemetry.io/otel/semconv/NEW VERSION package. The package contains semantic conventions from the NEW VERSION version of the OpenTelemetry Semantic Conventions. See the [migration documentation](https://link.gitcode.com/i/0ecd447125517fd85f3b4b6c4b74a1df) for information on how to upgrade from go.opentelemetry.io/otel/semconv/PREVIOUS VERSION. (#PR_NUMBER)提示把条目中的本次版本与上一版本都改对保持与仓库内实际 semconv 版本链一致。例如当前目录中每个semconv/v1.x.y子包都带一份 MIGRATION.md供使用方做跨版本迁移参考。3.3 更新全库 semconv imports新模块生成后代码库中所有对旧 semconv 的引用都要切换为新版本文档给出的迁移前后对照如下// Before semconv go.opentelemetry.io/otel/semconv/v1.37.0 go.opentelemetry.io/otel/semconv/v1.37.0/otelconv // After semconv go.opentelemetry.io/otel/semconv/v1.39.0 go.opentelemetry.io/otel/semconv/v1.39.0/otelconv替换完毕后运行make顶层 Makefile 的默认目标为precommit内含 generate、gofmt、lint、verify-mods、test 等全套自检确认没有编译或测试失败。3.3.1 属性变更的处理attribute changes部分 semconv 版本可能新增属性也可能影响正在使用的属性——可能是简单的改名也可能是合并属性、修改属性取值等更复杂的变化。处理原则是代码应迁移到语义约定中的新属性上但对于被取代的旧属性是否继续按旧名发射受OTEL_SEMCONV_STABILITY_OPT_IN环境变量控制即遵循约定中稳定属性可选 opt-in 旧行为的机制。文档给出一个完整的迁移追踪案例可参考opentelemetry-go 仓库 issue #7806。3.4 同步 go-contrib 仓库的 linter 约束由于本仓库升级了 semconv 主版本配套的opentelemetry-go-contrib仓库也需要同步修改其.golangci.yml强制使用新的 semconv 版本避免 contrib 继续编译旧的约定包。四、Breaking changes 校验与 contrib 兼容性验证在正式改版本号之前需先确认本次改动没有破坏公共 API。4.1make gorelease公共 API 校验运行make gorelease该命令逐个 module 调用 gorelease 工具用于检测公共 API 是否存在计划外的破坏性变更。从 Makefile 可以看出其实现gorelease目标展开为对所有go.mod目录OTEL_GO_MOD_DIRS即排除internal/tools外的全部子模块逐一执行gorelease/%进入每个目录后运行 gorelease 检查。如果发现 gorelease 本身存在问题可在 https://golang.org/issues/26420 跟踪反馈。4.2 验证对 contrib 仓库的影响如果本仓库改动会影响 contrib 仓库应按照 contrib 仓库RELEASING.md中的 Verify OTel changes 一节先行验证二者兼容性确保下游不出问题。五、Pre-Release确定 module set 版本并生成改动OpenTelemetry Go 是一个多模块仓库不同模块走不同版本号。版本编排全部集中在 versions.yaml其中用module-sets定义了四个模块集每个模块集有独立版本module set当前版本vendored 快照包含的典型模块stable-v1v1.44.0go.opentelemetry.io/otel、metric、sdk、sdk/metric、trace、exporters/otlp/*、exporters/zipkin、bridge/opencensus、bridge/opentracing等experimental-metricsv0.66.0exporters/prometheus、metric/xexperimental-logsv0.20.0log、sdk/log、exporters/otlp/otlplog/*、exporters/stdout/stdoutlogexperimental-schemav0.0.17schema同时文件还用excluded-modules排除internal/tools与trace/internal/telemetry/test这类不参与独立发版的内部模块用modulesversion-refs声明个别模块如exporters/stdout/stdouttrace、exporters/prometheus等的版本引用要同步写到其internal/version.go中保证编译期版本号常量与发布版本一致。发布时的第一步就是决定本次要发布哪些 module set把versions.yaml中对应version改为新版本号并提交到一个新分支。5.1 运行 prerelease随后在仓库中运行 prerelease 目标make prerelease MODSETmodule set它会生成一个名为prerelease_module set_new tag的分支包含所有版本改动例如把所有 go.mod 的依赖指向即将发布的新版本。对照 Makefile该目标先执行verify-mods即multimod verify校验 versions.yaml 与各 go.mod 一致性再执行$(MULTIMOD) prerelease -m ${MODSET}且强制要求设置MODSET环境变量。5.2 核对改动并合入发布分支git diff ...prerelease_module set_new tag该 diff 应把所有相关模块的版本统一改为new tag。确认无误后合入你的 pre-release 分支git merge prerelease_module set_new tag5.3 更新 Changelog版本改动就绪后同步维护 CHANGELOG.md确保本次发布所有相关改动都收录且语言要能让非本项目贡献者读懂。可用下面的命令直接核对自上一个 tag 以来的提交git --no-pager log --prettyoneline last tag..HEAD把Unreleased下的改动整体移入一个新章节标题格式为[new tag] - date of release对照真实文件的写法如 CHANGELOG.md 中的## [1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27一次多模块发布可在一个标题里并列列出各 module set 版本新章节必须放在!-- Released section --注释之下避免将来被工具覆盖该仓库正是用这条注释来划分已发布区与Unreleased 区详见 CHANGELOG.md更新文件底部所有版本间 compare 链接。5.4 推送并提 PR把改动推送到 upstream并在 GitHub 创建 Pull RequestPR 描述中要包含上述精选过的 Changelog 内容。六、Tag给每个子模块打标签并推送当包含全部版本改动的 PR 被合入主干后即可对合入 commit 打 tag。两个关键警告文档原意必须使用与 Pre-Release 阶段完全相同的 tag只要在 prerelease 与 tag 之间不修改versions.yaml就不会出错否则仓库会处于损坏状态。Go 模块一旦错误打 tag目前没有删除已错误标记的 Go 模块版本的办法对应 golang/go#34189错误推送会引发难以绕过的紧急问题因此推送前务必确认版本号正确。6.1 运行 add-tags对每个要发布的 module set 执行make add-tags MODSETmodule set COMMITcommit hashCOMMIT取合入 PR 后主干上的 commit hash。只有当前工作区HEAD不是正确 commit 时才必须显式传COMMIT。对照 Makefile它同样先跑verify-mods再执行$(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}——也就是由 multimod 依据versions.yaml里该 module set 的模块清单为每一个子模块打上path/version格式的 tag。6.2 推送所有 tag把 tag 推到 upstream注意不是你的 forkgit push upstream new tag git push upstream submodules-path/new tag ...需要把主模块 tag 与全部子模块 tag 一并推送。七、签名发布产物CNCF 合规为符合 CNCF 最佳实践需要对发布产物做 GPG 签名。从新 tag 的 tags 页面下载对应的.tar.gz与.zip归档签名前可用官方辅助脚本先核对归档内容查询本机 GPG 密钥 IDgpg --list-secret-keys --keyid-formatlong密钥 ID 即sec rsa4096/之后或类似位置的 16 位字符串设置环境变量并对两份归档做分离式 ASCII 签名export VERSIONversion # 例如 v1.32.0 export KEY_IDyour-gpg-key-id gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.tar.gz gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.zip校验签名gpg --verify opentelemetry-go-$VERSION.tar.gz.asc opentelemetry-go-$VERSION.tar.gz gpg --verify opentelemetry-go-$VERSION.zip.asc opentelemetry-go-$VERSION.zip最终会得到.tar.gz、.tar.gz.asc、.zip、.zip.asc四份产物。八、创建 GitHub Release最后为new tag在 GitHub 上创建 Release正文应包含本次发布对应的全部 Changelog release notes。重要GitHub Releases 一经创建即不可变。签名产物.tar.gz、.tar.gz.asc、.zip、.zip.asc必须在创建 Release 时就上传之后无法再追加或修改。九、Post-Release 收尾9.1 发布 contrib 仓库确认无误后应基于本次发布为opentelemetry-go-contrib仓库制作对应 release该仓库有自己的 RELEASING.md 流程。9.2 更新官网 Go 文档同步更新 OpenTelemetry 官网中content/en/docs/languages/go目录下的 Go instrumentation 文档把引用的包版本号 bump 到刚发布的版本并确保所有代码示例仍可编译、内容准确。9.3 关闭里程碑发布后把本版本修复的所有 issue 与合入的所有 PR 归入对应里程碑便于追踪每次发布包含的改动用仓库内的搜索条件找出尚未归入里程碑的已关闭 issueis:issue no:milestone is:closed reason:completed等条件组合找出尚未归入里程碑的已合入 PRis:pr no:milestone is:merged。全部归入后关闭该里程碑。9.4 关闭Version ReleaseissueVersion Releaseissue 中的 todo 全部完成后关闭该 issue一次发布正式结束。十、结语把发布流程沉淀为可核对的 SOP回顾整个流程可以看出opentelemetry-go 的发布高度工具化versions.yaml是唯一的版本事实来源multimod负责按 module set 统一改版本与打 tagsemconv-generate通过 weaver 容器把语义约定模型转成 Go 代码gorelease守护公共 API 兼容性GPG 签名满足 CNCF 产物合规CHANGELOG 的!-- Released section --注释机制则保证发布历史不被后续改写覆盖。这些机制全部可以在当前仓库的 versions.yaml、Makefile 与 CHANGELOG.md 中逐一印证对于需要维护一主仓多子模块版本的 Go 项目而言这套由 issue 驱动、工具兜底、人工复核的发布 SOP 本身就是一份极佳的工程参考。【免费下载链接】kubernetesProduction-Grade Container Scheduling and Management项目地址: https://gitcode.com/GitHub_Trending/kuber/kubernetes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进