首页
/ OpenTelemetry Go SDK 版本发布全流程:以 Moby 仓库中 vendored 的 otel 模块为例

OpenTelemetry Go SDK 版本发布全流程:以 Moby 仓库中 vendored 的 otel 模块为例

2026-09-07 23:15:07作者:鲍丁臣Ursa

导读

本文以当前仓库中 vendored 的 vendor/go.opentelemetry.io/otel/RELEASING.md 为核心骨架,系统讲解 opentelemetry-go(go.opentelemetry.io/otel)从创建 Version Release 跟踪 issue、升级 Semantic Conventions、校验 breaking changes,到 pre-release、打 tag、GPG 签名制品、发布 GitHub Release 以及 post-release 收尾的完整操作链路。读者阅读后可掌握该 Go 观测性 SDK 的模块化版本发布规范,并能在 vendor/go.opentelemetry.io/otel 目录内对照 Makefile、versions.yaml、CHANGELOG 与 semconv 子包核实每一步的底层实现与预期产物。

一、前置认知:这份文档在仓库中的位置与角色

该文件位于 Moby 仓库的第三方依赖目录下:

理解这份文档前需要知道两个关键背景:

  1. 本文档描述的是上游 opentelemetry-go 仓库的发布流程。文中的发布操作(推分支、打 tag、签名制品、发 Release)发生在 opentelemetry-go 自身仓库内;而 Moby 仓库将其以 vendor 快照方式引入,因此读者可以从本仓库的 vendored 副本核对其中的 Makefile 目标、module 集合与 semconv 布局,实际执行发布仍属于上游仓库维护者的职责范围。
  2. 发布以“module set”为单位而非单一 module。otel-go 采用多 Go module 布局,versions.yaml 将众多 module 组织为多个 module set(详见下文),因此每次发布需要批量、一致地推进一批 module 的版本。

二、创建 Version Release 跟踪 issue

发布的第一步是在仓库中创建一个 Version Release issue,用于跟踪整个发布流程。该 issue 承担两重职责:

  • 将发布流程拆分为可勾选的 todo 清单(semconv 升级、pre-release、tag、签名、Release、里程碑收尾等);
  • 在流程结束时(Post-Release 阶段)勾选并关闭该 issue,作为一次发布闭环的存档。

从文档结构看,issue 与 milestone、CHANGELOG 一起构成“可追溯”的发布证据链:每个 PR、每个 issue 都能对应到它被合入/修复的具体版本。

三、Semantic Convention 升级(前置步骤)

注:原文定义的外部链接(OpenTelemetry Semantic Conventions 规范仓库等)请读者按需在上游查询;下面内容聚焦于本仓库可核对的流程与命令本身。

每次上游 [OpenTelemetry Semantic Conventions] 发布新版本,都意味着 go.opentelemetry.io/otel/semconv 包需要重新生成,以携带新版本的语义约定。

3.1 生成新 semconv 子包

生成操作由 semconv-generate 这个 make target 完成。发布者需要:

  1. TAG 环境变量设置为要生成的 semantic conventions 版本标签;
  2. 在本仓库(otel-go 根目录)执行 make semconv-generate

文档给出的标准示例:

export TAG="v1.30.0" # Change to the release version you are generating.
make semconv-generate # Uses the exported TAG.

在本仓库 vendored 副本中可以找到该 target 的真实实现:vendor/go.opentelemetry.io/otel/Makefile#L289-L313。实现要点包括:

  • TAG 未设置时直接报错退出(TAG unset: missing opentelemetry semantic-conventions tag),强制发布者显式声明版本;
  • 通过 semconvkit 工具与 weaver 镜像从指定 tag 拉取语义约定 registry 源码并渲染 Go 代码到 semconv/<TAG>/ 目录;
  • 生成完毕后调用 $(SEMCONVKIT) 对产物做后处理。

执行完成后,仓库会新增一个 semconv/<NEW VERSION> 子包。发布者应先确认生成内容正确,再提交 PR 合入。

本仓库 vendored 副本中已存在多个历史版本子包,可作为“生成后应长什么样”的参照物:如 vendor/go.opentelemetry.io/otel/semconv/v1.37.0(含 schema.go、exception.go、attribute_group.go 等)与 vendor/go.opentelemetry.io/otel/semconv/v1.43.0(额外包含 httpconv、otelconv、rpcconv 等转换辅助子包)。

3.2 更新 CHANGELOG

新 semconv 子包加入后,需要同步在 vendor/go.opentelemetry.io/otel/CHANGELOG.md 中登记变更,文档给出的 changelog 条目模板如下:

- 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://gitcode.com/GitHub_Trending/mo/moby/blob/252bd664babaa81e2c579352e78a09bab0160f4f/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/MIGRATION.md?utm_source=gitcode_repo_files) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/<PREVIOUS VERSION>`. (#PR_NUMBER)

Tip: 将 release 与 prior version 替换为实际的版本号。

仓库中的 CHANGELOG 恰好提供了这种条目的实例,例如 v1.45.0/0.67.0/0.21.0/0.0.18 一节中“Add the go.opentelemetry.io/otel/semconv/v1.42.0 package.”的记录;配套的迁移文档也能在本仓库直接看到,例如 vendor/go.opentelemetry.io/otel/semconv/v1.43.0/MIGRATION.md(说明 v1.43.0 可作 v1.42.0 的 drop-in 替代)。

3.3 更新全代码库的 semconv 导入路径

新 semconv module 生成后,需要把整个代码库中所有 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 检查是否存在编译失败或测试失败。

3.4 处理 attribute 变更

某些 semconv 版本可能新增 attribute,或影响当前正在使用的 attribute——变更可能从简单重命名,到更复杂的“合并 attribute / 属性值语义改变”。发布者应将代码迁移到取代旧 attribute 的新 attribute,以贴合语义约定;但考虑到兼容性,旧 attribute 仍可能在 OTEL_SEMCONV_STABILITY_OPT_IN 环境变量的控制下继续被输出。

对于这种迁移应该如何跟踪与执行,文档给出了上游 issue(#7806)作为参考案例,可结合该 issue 了解实践中属性迁移的完整过程。

3.5 Go contrib linter 更新

semconv 版本升级通常还牵动 opentelemetry-go-contrib 仓库:需要在其 .golangci.yml 中强制使用新 semconv 版本,确保 contrib 仓库的静态检查与实际依赖保持一致。

四、Breaking Changes 校验

对外发布公共 API 之前,必须确保没有引入“意外”的破坏性变更。执行:

make gorelease

该 target 调用 gorelease 工具(golang.org/x/exp/cmd/gorelease)比对公共 API 变化。本仓库的 Makefile 中其实现位于 vendor/go.opentelemetry.io/otel/Makefile#L315-L322,它针对所有 Go module 逐一运行 gorelease 输出差异报告。若发现问题,可在上游 golang 的 issue(#26420)处上报或排查。

五、验证对 contrib 仓库的兼容性

若主仓库的改动会影响 contrib 仓库(opentelemetry-go-contrib),发布前需要按 contrib 仓库 RELEASING.md 中 “Verify OTel changes” 一节描述的步骤,验证主仓库改动与 contrib 仓库的兼容性。该步骤的核心价值在于:otel-go 是生态底座,主仓库 API 或 semconv 层面的改动会级联影响上层 instrumentation 库,提前在 contrib 层面跑通编译与测试能显著降低正式发布后的回归风险。

六、Pre-Release(发布前准备)

6.1 决定 module set 并更新 versions.yaml

首先决定本次将发布哪些 module set,并在 versions.yaml 中更新它们的版本号,随后在新分支上提交该变更。

module set 是什么?本仓库 vendored 的 vendor/go.opentelemetry.io/otel/versions.yaml 提供了直观样例:例如 stable-v1 集合当前版本 v1.46.0,成员包含 go.opentelemetry.io/otel 主 module、metrictracesdksdk/metric、各 OTLP/stdout/zipkin exporter 等;另有 experimental-metrics(v0.68.0)、experimental-logs(v0.22.0)、experimental-schema(v0.0.19)等集合,分别服务于不同稳定性阶段的 API(v1.x 稳定 / v0.x 实验)。这正是“一次发布推进一组 module 到同一版本”的机制来源,也是 CHANGELOG 标题写作 [1.46.0/0.68.0/0.22.0/0.0.19] - <date> 的原因。

6.2 运行 prerelease target

更新子模块的 go.mod,使其依赖下一步即将发生的新版本发布。然后:

  1. 执行 make prerelease,并指定要发布的 module set。它会创建分支 prerelease_<module set>_<new tag>,承载所有发布相关改动:

    make prerelease MODSET=<module set>
    
  2. 核对改动,确认所有 module 的版本都被改写为新 tag:

    git diff ...prerelease_<module set>_<new tag>
    

    确认无误后,将改动合入发布前分支:

    git merge prerelease_<module set>_<new tag>
    

在本仓库 Makefile 中可以查看该 target 的真实执行逻辑:vendor/go.opentelemetry.io/otel/Makefile#L328-L331——它依赖 multimod 工具,先执行 verify-mods,再调用 $(MULTIMOD) prerelease -m ${MODSET}MODSET 未设置会直接报错。multimod 正是依据 versions.yaml 中 module-set 定义完成批量版本改写的核心工具。

6.3 更新 Changelog

  • 确保本次发布所有相关变更均已收录,且行文能让非贡献者也读懂。可用如下命令直接审查自上个 tag 以来的提交:
    git --no-pager log --pretty=oneline "<last tag>..HEAD"
    
  • Unreleased 下的所有变更迁移到新的版本小节,标题格式为 [<new tag>] - <date of release>
  • 确保新小节位于“released section”注释(如 <!-- Released section -->)之下,以在未来的发布中被自动保护、不被覆盖。
  • 更新文末所有相关链接。

本仓库的 vendor/go.opentelemetry.io/otel/CHANGELOG.md 恰好展示了这套机制的最终形态:## [Unreleased] 之下紧跟 <!-- Released section --> 注释与 <!-- Don't change this section unless doing release --> 保护性注释,随后是按时间倒序排列的历史版本小节。

6.4 提交 PR

将改动推送至 upstream 并在 GitHub 创建 Pull Request,PR 描述中必须包含上述整理好的 Changelog 变更内容。

七、Tag:为合并后的 commit 打标签

所有版本变更的 PR 被批准并合并后,即可为合并 commit 打 tag。

IMPORTANT:打 tag 必须与 Pre-Release 步骤使用完全相同的 tag!否则会留下 broken state。只要 pre-release 之后不再改动 versions.yaml,通常不会出错。

IMPORTANT:Go module 目前无法删除被错误标记的版本(上游 golang issue #34189),因此必须确保推送到上游的版本号正确无误,否则将引发难以规避的连带问题。

操作步骤:

  1. 对每个要发布的 module set,用主分支上合并 PR 的 <commit-hash> 执行 make add-tags

    make add-tags MODSET=<module set> COMMIT=<commit hash>
    

    只有当工作目录当前 HEAD 不是目标 commit 时才需要显式传 COMMIT

  2. 将 tag 推送到 upstream remote(注意是上游仓库而非 fork),并确保所有子模块的 tag 一并推送:

    git push upstream <new tag>
    git push upstream <submodules-path/new tag>
    ...
    

其底层实现同样位于 vendor/go.opentelemetry.io/otel/Makefile#L333-L337add-tags 依赖 verify-mods 并调用 $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT},由 multimod 依据 module-set 定义与指定 commit 批量生成各 module 的版本 tag。由于 vendored 副本中 go.mod 的 module 与子目录层级(如 semconv/v1.37.0、semconv/v1.43.0 等独立子 module)清晰可查,可以直观对应“为何需要逐个子 module 分别推送 tag”。

八、签名制品(Sign artifacts)

为遵循 CNCF 最佳实践,需要对发布制品做签名:

  1. 从 releases tags 页面下载新 release tag 对应的 .tar.gz.zip 归档,两者均需使用发布者的 GPG 密钥签名。签名前可用上游提供的脚本核验归档内容。
  2. 查看 GPG 密钥 ID:
    gpg --list-secret-keys --keyid-format=long
    
    密钥 ID 即 sec rsa4096/(或类似字段)之后的 16 位字符串。
  3. 设置环境变量并对两个制品签名:
    export VERSION="<version>"  # e.g., v1.32.0
    export KEY_ID="<your-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
    
  4. 校验签名:
    gpg --verify opentelemetry-go-$VERSION.tar.gz.asc opentelemetry-go-$VERSION.tar.gz
    gpg --verify opentelemetry-go-$VERSION.zip.asc opentelemetry-go-$VERSION.zip
    

九、Release:创建 GitHub Release

在 GitHub 上为新 tag 创建 Release,正文应包含本次发布在 Changelog 中的全部 release notes。

IMPORTANT:GitHub Releases 一经创建即不可变(immutable)。签名制品(.tar.gz.tar.gz.asc.zip.zip.asc必须在创建 Release 时一并上传,之后无法补充或修改。

十、Post-Release 收尾

10.1 Contrib 仓库发布

验证通过后,需同步为使用本次版本的 contrib 仓库(opentelemetry-go-contrib)制作对应的 release,确保生态版本配套推进。

10.2 官网文档更新

更新 OpenTelemetry 官网中 Go instrumentation 文档页(content/en/docs/languages/go)。重点是:

  • 将文中引用的各包版本号提升为本次发布的最新版本;
  • 重新验证所有代码示例仍可编译且准确无误。

10.3 收尾 milestone

每次 release 完成后,确保本次发布修复的 issue 与合入的 PR 都被归入对应 milestone,以便追踪每个版本包含了哪些变更:

  • 用 GitHub 搜索找出尚未归入 milestone 的已关闭 issue(可加 no:milestone is:closed 等过滤条件,并排除 Stale 标签、只保留 linked:pr 的问题);
  • 找出尚未归入 milestone 的已合并 PR(条件类似:no:milestone is:merged)。

全部关联 issue/PR 归入 milestone 后,关闭该 milestone。

10.4 关闭 Version Release issue

Version Release issue 的 todo 清单全部完成后,关闭该 issue,一次完整的发布流程就此闭环。

总结

整个发布流程可以凝练为一条清晰的责任链:

  1. 跟踪:创建 Version Release issue,锁定本次发布范围;
  2. 内容准备:升级 semconv(TAG + make semconv-generate)→ 迁移导入 → 更新 CHANGELOG,再用 make gorelease 校验无意外破坏性变更;
  3. 版本改写:更新 versions.yamlmake prerelease MODSET=... 批量推进 module 版本 → 合并 PR;
  4. 固化make add-tags MODSET=... COMMIT=... 打 tag 并推送所有子模块 tag;
  5. 可信分发:GPG 签名 .tar.gz/.zip 制品 → 创建不可变的 GitHub Release 并上传签名产物;
  6. 生态收尾:发布 contrib 版本、更新官网文档、归拢并关闭 milestone 与跟踪 issue。

这套流程中反复出现的 versions.yaml、Makefile target(semconv-generate / prerelease / add-tags / gorelease)与 CHANGELOG 约定,都可以在当前仓库 vendor/go.opentelemetry.io/otel 目录下找到真实实现与历史样例,值得结合阅读,从而更准确地把控多 Go module 项目规模化发布时的版本一致性与制品可验证性。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388