news 2026/10/3 8:21:12

opentelemetry-go 版本发布全流程指南:语义约定升级、多模块打标签与制品签名

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
opentelemetry-go 版本发布全流程指南:语义约定升级、多模块打标签与制品签名
  • 可观测性

【免费下载链接】opentelemetry-go

OpenTelemetry Go API and SDK

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

导读

本文以 RELEASING.md 为核心骨架,系统讲解 OpenTelemetry Go(opentelemetry-go)从语义约定升级、破坏性变更验证、多模块预发布与打标签,到制品签名、创建 Release 与发布后收尾的完整发布流程。读者将掌握semconv-generate、prerelease、add-tags、gorelease等 Make 目标与multimod工具链的实际用法,理解versions.yaml模块集(module sets)的版本管理机制,并能独立完成一次符合 CNCF 最佳实践的版本发布。

1. 发布流程全景:从 Version Release Issue 开始

任何一次版本发布都始于一个版本发布跟踪 Issue(Version Release issue)。它的作用有二:一是作为本次发布的 TODO 清单,逐项记录发布过程中的每个环节;二是在发布完成后统一关闭,形成可追溯的记录。

整个发布流程按时间线可分为六个阶段:

  1. 语义约定升级(如本次发布涉及 semconv 更新);
  2. 破坏性变更验证(make gorelease)与contrib 仓库兼容性验证;
  3. 预发布(更新versions.yaml、生成发布分支、整理 CHANGELOG);
  4. 打标签(make add-tags+ 推送 tag 到 upstream);
  5. 签名制品(GPG 签名.tar.gz与.zip);
  6. 创建 GitHub Release及发布后收尾(contrib 发布、官网文档更新、关闭里程碑与 Issue)。

下文逐一展开。

2. 语义约定升级(Semantic Convention Upgrade)

OpenTelemetry 的语义约定(Semantic Conventions)是跨语言统一的属性、指标命名规范。每次 OpenTelemetry Semantic Conventions 发布新版本,opentelemetry-go仓库中的semconv包都需要随之重新生成,并作为新的独立子包发布,例如仓库中现有的 semconv/v1.4.0、semconv/v1.34.0、semconv/v1.43.0 等一系列版本目录。

2.1 语义约定代码生成:make semconv-generate

生成新版本 semconv 包的核心入口是semconv-generate这个 Make 目标,共两步:

  1. 将TAG环境变量设置为要生成的语义约定标签(tag);
  2. 在本仓库根目录运行make semconv-generate(该目标会自动读取已导出的TAG)。

官方示例:

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

运行完成后,semconv 目录下会生成一个新的版本子包。提交 Pull Request 前,务必人工确认生成结果是否正确。

从 Makefile 的源码实现可以看到该目标的真实执行链路:

  • 首先强制校验TAG必须已设置,否则直接报错退出(TAG unset: missing opentelemetry semantic-conventions tag);
  • 创建semconv/<TAG>目标目录;
  • 通过 Docker 运行otel/weaver镜像(镜像版本定义在 dependencies.Dockerfile 的weaver阶段),将 semconv/templates/registry/go 下的模板目录以只读方式挂载,并指定--registry指向语义约定仓库对应 tag 的 zip 归档,执行registry generate生成 Go 代码;
  • 最后调用仓库自研工具semconvkit(源码位于 internal/tools/semconvkit/main.go)做二次加工,补齐 migration 文档等仓库特有产物。

模板目录中的 weaver.yaml 定义了生成规则:例如排除aspnetcore、nodejs等语言专属命名空间,指定attribute_group.go、metric.go的输出文件名与过滤器,以及string -> String、int[] -> IntSlice等类型映射表。生成产物包括常量形式的属性 Key(见 attribute_group.go,以AndroidAppStateKey = attribute.Key("android.app.state")为例)、SchemaURL(见 schema.go,形如https://opentelemetry.io/schemas/1.34.0)以及各领域的xxxconv辅助包(如httpconv、dbconv、k8sconv)。

2.2 同步更新 CHANGELOG

新 semconv 包加入后,CHANGELOG.md 需要记录这一变更,官方给出了标准条目模板:

- 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/2333a14b225d5319b4aa8e7d21064e1b) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/<PREVIOUS VERSION>`. (#PR_NUMBER)

Tip:将<NEW VERSION>与<PREVIOUS VERSION>替换为本次升级前后的实际版本号。

注意这里的迁移文档链接应指向对应版本目录下的 MIGRATION.md。该文档由semconvkit自动生成(模板见 internal/tools/semconvkit/templates/MIGRATION.md.tmpl),它会对比上一版本与当前版本包中导出的声明,自动罗列出 Renames 与 Removed 清单。从 internal/tools/semconvkit/main.go 的prevVer函数可以看到,工具会扫描semconv/目录下所有符合 semver 的版本目录,自动选取"小于当前版本且最接近"的版本作为迁移对比基准。

2.3 更新 semconv 导入

生成新模块后,需要把整个代码库中所有引用旧 semconv 的 import 替换为新版本。典型改动如下:

// 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"

说明:上述版本号仅作示例,实际以本次升级目标版本为准。以当前仓库为例,代码中大量文件(如 bridge/opentracing/mock.go、exporters/otlp/otlplog/otlploggrpc下的观测代码)已统一引用semconv/v1.43.0,替换时可先用search_in_files类工具全库搜索旧版本号,确保无遗漏。

替换完成后运行make检查编译与测试是否通过。仓库 Makefile 的默认目标precommit(见 Makefile)会依次执行generate、toolchain-check、license-check、misspell、go-mod-tidy、golangci-lint-fix、verify-readmes、verify-mods与test-default,可用于发布前的一次性全面校验。

2.4 属性变更的处理与 OTEL_SEMCONV_STABILITY_OPT_IN

部分 semconv 版本会新增属性,或影响当前正在使用的属性——改动可能只是简单重命名,也可能是更复杂的合并属性、修改属性值类型等。原则是:代码应迁移到取代旧属性的新属性上,遵循最新的语义约定。

同时需要了解OTEL_SEMCONV_STABILITY_OPT_IN环境变量:当用户设置该变量时,根据约定,旧属性可能仍会随遥测数据一并发出,用于兼容过渡。因此迁移时既要更新代码使用新属性,也要考虑对旧属性发射行为的兼容预期。

此类迁移的跟踪与执行方式可参考社区维护的 issue #7806 中的案例讨论。

2.5 更新 Go contrib 仓库的 linter 配置

若本次 semconv 升级会影响opentelemetry-go-contrib仓库,还需同步更新该仓库根目录下的.golangci.yml,强制要求 contrib 使用新的 semconv 版本,从而保证整个 OpenTelemetry Go 生态的语义约定版本保持一致。

3. 破坏性变更验证:make gorelease

公共 API 的意外变更对 Go 模块发布是致命问题。发布前必须运行:

make gorelease

该命令会调用 gorelease 实现看,gorelease目标会遍历仓库中所有go.mod 所在目录逐个执行gorelease检查,即主模块与全部子模块都会覆盖到。

若发现 gorelease 本身的问题,可在 Go 官方 issue tracker(golang.org/issues/26420)中报告。工具对应的 Go 依赖声明在 internal/tools/tools.go 中(golang.org/x/exp/cmd/gorelease)。

4. 验证 contrib 仓库兼容性

如果主仓库的变更会影响 contrib 仓库,必须在合并前验证两者兼容。具体步骤遵循 contrib 仓库自身的 RELEASING.md 中 "Verify OTel changes" 一节:通常是先本地替换主仓库依赖、运行 contrib 的测试套件,确认无破坏后,主仓库的 PR 才可安全合并。

5. 预发布(Pre-Release):versions.yaml 与 multimod

预发布阶段的核心工作是确定本次要发布哪些模块集(module set)并更新它们的版本号。

5.1 更新 versions.yaml

首先在 versions.yaml 中为要发布的模块集设置新版本,并将该变更提交到新分支。当前仓库的模块集划分如下(以仓库现状为准):

模块集当前版本包含的典型模块
stable-v1v1.47.0-rc.1go.opentelemetry.io/otel、otel/sdk、otel/trace、otel/metric、otel/log及各 OTLP/stdout/zipkin exporter 等
experimental-metricsv0.68.0exporters/prometheus、metric/x
experimental-logsv0.22.0log/logtest、sdk/log/logtest、各 otlplog/stdoutlog exporter
experimental-tracesv0.1.0sdk/trace/x
experimental-schemav0.0.19schema

可见本仓库采用"稳定模块主版本号 + 实验模块独立 0.x 版本号"的并行版本策略。versions.yaml还通过modules段的version-refs将各子模块的版本号与自身internal/version.go文件绑定(例如otel/exporters/stdout/stdouttrace对应 internal/version.go),主模块版本则体现于根目录 version.go 的Version()函数。

5.2 make prerelease 生成发布分支

更新完versions.yaml后,还需同步更新各子模块 go.mod 中对新版本的依赖引用。运行预发布目标:

make prerelease MODSET=<module set>

该命令会创建一个名为prerelease_<module set>_<new tag>的分支,包含全部发布所需的版本改动。从 Makefile 实现看,prerelease首先执行verify-mods(即multimod verify,校验versions.yaml与各模块声明的一致性),然后调用multimod prerelease -m ${MODSET}完成版本改写,且强制要求MODSET环境变量已设置。

5.3 审阅变更并合入

用 git diff 审阅生成的分支改动:

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

正常结果应是所有模块的版本都被改写为<new tag>。确认无误后,将其合并到你的预发布分支:

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

5.4 更新 CHANGELOG

发布前必须整理 CHANGELOG.md,要点如下:

  • 确保本次发布的所有相关变更都已收录,且措辞能让非贡献者看懂。可用以下命令直接查看自上个 tag 以来的全部提交,作为核对依据:

    git --no-pager log --pretty=oneline "<last tag>..HEAD"
  • 将Unreleased段的所有内容移动到新版本小节中,标题遵循[<new tag>] - <date of release>格式(Keep a Changelog 风格,见 CHANGELOG.md 头部说明);

  • 新小节必须位于<!-- Released section -->注释之下(该注释标记已发布区段的起始位置),避免后续被自动生成流程覆盖;

  • 同步更新文件底部的所有版本链接。

5.5 推送并提交 PR

将改动推送到 upstream,创建 Pull Request,并在 PR 描述中附上整理好的 CHANGELOG 内容(即本次发布的 release notes)。

6. 打标签(Tag):make add-tags

PR 合入后即可对合并提交打标签。必须使用与预发布阶段完全相同的 tag,否则会破坏整个发布状态——只要预发布与打标签之间不修改versions.yaml,tag 就能保持一致。

另外有一个 Go 生态的硬约束需要特别注意:Go 模块目前没有删除错误 tag 的能力(对应 Go 官方 issue #34189)。一旦把错误的版本推送到 upstream,将很难补救,历史上曾因此引发过不小的事故(见 opentelemetry-go issue #331 的教训),因此推送前务必反复核对版本号。

打标签命令:

make add-tags MODSET=<module set> COMMIT=<commit hash>
  • COMMIT指向主分支上合并 PR 的提交哈希;只有当当前工作目录的HEAD不是正确提交时才需要显式指定,否则可省略(Makefile 中COMMIT ?= "HEAD",默认取当前 HEAD);
  • add-tags同样先执行verify-mods校验,再调用multimod tag -m ${MODSET} -c ${COMMIT}为模块集内所有模块生成 tag。

然后推送所有 tag 到 upstream(注意是主仓库而非你的 fork),主模块与各子模块的 tag 都要推送:

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

7. 签名制品(Sign artifacts)

为满足 CNCF 最佳实践,发布制品需要 GPG 签名。步骤为:

  1. 从 tag 页面下载新发布 tag 对应的.tar.gz与.zip两个归档;
  2. 建议先用社区提供的校验脚本(attest-sh)核对归档内容完整性,再签名;
  3. 查询本机 GPG 密钥 ID:
gpg --list-secret-keys --keyid-format=long

密钥 ID 是sec rsa4096/(或类似字段)之后的 16 位字符串。

  1. 设置环境变量并签名两个归档:
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
  1. 验证签名:
gpg --verify opentelemetry-go-$VERSION.tar.gz.asc opentelemetry-go-$VERSION.tar.gz gpg --verify opentelemetry-go-$VERSION.zip.asc opentelemetry-go-$VERSION.zip

签名会生成.asc格式的独立签名文件(.tar.gz.asc与.zip.asc),与归档文件一并用于后续 Release 上传。

8. 创建 GitHub Release

最后为<new tag>创建 Release,正文内容包含本次发布在 CHANGELOG 中的全部 release notes。

关键约束:GitHub Release 一经创建即不可变(immutable),签名制品(.tar.gz、.tar.gz.asc、.zip、.zip.asc)必须在创建 Release 时一并上传,因为之后无法再添加或修改附件。

9. 发布后(Post-Release)

9.1 contrib 仓库发布

验证通过后,需要同步为opentelemetry-go-contrib仓库发布一个基于本次版本的新 Release,使 contrib 生态引用到刚发布的模块版本。

9.2 官网文档更新

更新 OpenTelemetry 官网中 Go 语言 instrumentation 文档(位于官网内容仓库的content/en/docs/languages/go目录)。重点包括:将文档中引用的所有包版本号提升为刚发布的最新版本,并确保全部代码示例仍可编译、内容准确。

9.3 关闭里程碑

为便于追踪每个版本包含了哪些变更,发布后需确保本次发布修复的 issue 与合入的 PR 都归入对应里程碑:

  • 查找未归入里程碑的已关闭 issue(可按"无里程碑、已关闭、已完成原因、已关联 PR、排除 Stale 标签"等条件检索);
  • 查找未归入里程碑的已合并 PR(按"无里程碑、已合并"条件检索);
  • 全部归入后关闭该里程碑。

9.4 关闭 Version Release Issue

当Version Releaseissue 中的 TODO 清单全部完成(制品签名、Release 创建、contrib 发布、文档更新、里程碑关闭等),关闭该 issue,本次发布流程即告结束。

附录:发布工具链速览

本次流程涉及的核心工具与 Make 目标汇总:

工具/目标用途源码/配置位置
semconv-generate生成指定 TAG 的 semconv 子包(基于 weaver + semconvkit)Makefile
semconvkitsemconv 代码二次生成、MIGRATION.md 自动对比internal/tools/semconvkit/main.go
multimod多模块版本管理(verify/prerelease/tag)Makefile
gorelease公共 API 破坏性变更检查Makefile、internal/tools/tools.go
versions.yaml模块集(module sets)版本声明中心versions.yaml
weaver 模板semconv 生成规则(属性/指标过滤器、类型映射)semconv/templates/registry/go/weaver.yaml
crosslink仓库内多 go.mod 间依赖同步Makefile

发布者只要遵循"Issue 跟踪 → 语义约定升级 → API 兼容验证 → 预发布 → 打标签 → 签名 → Release → 收尾"这条主线,并严格保证 tag 与versions.yaml的一致性与制品的完整签名,就能稳定地完成一次 OpenTelemetry Go 版本发布。

  • 可观测性

【免费下载链接】opentelemetry-go

OpenTelemetry Go API and SDK

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

相关推荐

上一篇:TeslaMate数据库迁移终极指南:安全升级与数据无缝转移策略
下一篇:3步实现JVFloatLabeledTextField完美适配:从代码到多设备兼容

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

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

agno Agent 输入输出实用指南:6 个机制控制它说什么、怎么说

agno Agent 输入输出实用指南&#xff1a;6 个机制控制它说什么、怎么说 【免费下载链接】agno Build, run, and manage agent platforms. 项目地址: https://gitcode.com/GitHub_Trending/ag/agno agno 是一个用 Python 构建、运行和管理 Agent 平台的框架。实际用起来…

作者头像 李华
网站建设 2026/10/3 8:15:11

Mac 窗口管理只按一个键:Loop 分屏快捷键完整指南

Mac 窗口管理只按一个键&#xff1a;Loop 分屏快捷键完整指南 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop Loop 是一款开源的 Mac 窗口管理工具&#xff1a;按下默认触发键 fn 加方向键&#xff0c;…

作者头像 李华