Grafana Tempo 仓库内嵌的 OpenTelemetry Go 官方发布流程全解读:从语义约定升级到多模块打 tag

发布时间:2026/9/19 12:14:23
Grafana Tempo 仓库内嵌的 OpenTelemetry Go 官方发布流程全解读:从语义约定升级到多模块打 tag 后端可观测性链路追踪【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址https://gitcode.com/GitHub_Trending/tempo1/tempo点击查看免费下载本仓库Grafana Tempo作为分布式追踪后端其 Go 依赖go.opentelemetry.io/otel当前锁定 v1.44.0在 vendor 目录中完整保留了上游官方的RELEASING.md发布流程文档。本文将这份文档作为主体围绕语义约定Semantic Conventions升级、破坏性变更校验、预发布、打 tag、签名工件与发布后收尾等关键环节逐条展开讲解并结合仓库内的Makefile、versions.yaml、CHANGELOG.md、verify_released_changelog.sh以及 semconv 子包等真实文件帮助读者理解一个大型多模块 Go 项目是如何规范、可复现地完成一次版本发布的。输出文章深入解析 OpenTelemetry Go 多模块发布流程基于 Grafana Tempo 仓库中 RELEASING.md 的完整拆解在 Grafana Tempo 的 Go 依赖树中go.opentelemetry.io/otel当前版本 v1.44.0作为分布式追踪与遥测的核心库被大量使用其 vendor 目录下完整保留了上游官方的发布流程文档 RELEASING.md。这份文档不仅是 OTel Go 维护者的操作手册更是一个多模块仓库 语义化版本 自动化工具链发布工程的绝佳范本。本文以该文档为骨架逐阶段拆解发布流程并结合仓库内真实的 Makefile、versions.yaml、CHANGELOG 与 semconv 子包等源码证据说明每一步为什么这么做、底层由什么驱动让读者既能照做一次发布也能理解背后的工程机制。一、发布前奏创建 Version Release 跟踪 Issue任何一次发布都始于一个明确的跟踪载体。文档要求先在 GitHub 上创建Version Releaseissue用于串起从语义约定升级到最终发布、收尾的所有待办项。这一步的价值在于让发布过程可审计、可追踪每个阶段的状态都能在 issue 的 todo list 中体现让社区成员尤其是非维护者能够看到当前发布进度方便协同与反馈为后续 Close the milestone 阶段提供对照依据确保该版本所有已合并 PR 都被记录。从仓库实际状态看CHANGELOG.md 顶部即为[Unreleased]区块与!-- Released section --注释标记最新已发布版本为[1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27这说明该仓库采取一次多模块联合发版的节奏与文档描述的流程完全一致。二、语义约定Semantic Conventions升级OpenTelemetry 的语义约定semconv定义了 span 属性、指标名称等遥测数据的标准命名。每次上游open-telemetry/semantic-conventions发布新版本OTel Go 都需要重新生成对应的semconv/vX.Y.Z子包。这是整个发布流程中技术含量最高、最容易出错的一步。2.1 通过 semconv-generate 生成新版本子包文档给出的操作方式是基于环境变量TAG驱动 Makefile 目标export TAGv1.30.0 # 换成你要生成的目标版本 make semconv-generate # 使用导出的 TAG在仓库的 Makefile 中可以找到semconv-generate的真实实现它揭示了底层机制远比表面命令复杂前置校验[ $(TAG) ] || ( echo TAG unset: missing opentelemetry semantic-conventions tag; exit 1 )强制要求必须显式设置TAG防止误生成。目录准备mkdir -p $(PWD)/semconv/${TAG}为生成的子包创建目标目录同时mkdir -p ~/.weaver用于缓存 weaver 工具下载的 semconv 仓库。weaver 容器生成通过docker run --rm启动$(WEAVER_IMAGE)从dependencies.Dockerfile中解析出来的 weaver 镜像执行registry generate --registryhttps://github.com/open-telemetry/semantic-conventions/archive/refs/tags/$(TAG).zip[model] --templates... --param tag$(TAG) go /home/weaver/target即从指定 tag 的语义约定模型归档中渲染出 Go 代码。收尾处理$(SEMCONVKIT) -semconv semconv/ -tag $(TAG)调用 semconv 生成工具同样来自go.opentelemetry.io/build-tools做最终的包整理。生成完成后应检查semconv目录下是否出现了对应版本子包。仓库当前实际存在的版本包括 semconv/v1.18.0、v1.21.0、v1.25.0、v1.26.0、v1.34.0、v1.37.0、v1.38.0、v1.40.0、semconv/v1.41.0 等这些正是历次发布累积下来的结果也印证了每个语义约定大版本对应一个独立子包的版本策略——子包版本号与仓库主模块版本号互相独立。生成后必须同步更新 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 for information on how to upgrade from go.opentelemetry.io/otel/semconv/PREVIOUS VERSION. (#PR_NUMBER)仓库中实际的 CHANGELOG 条目与此完全吻合例如 v1.41.0 的条目- Add go.opentelemetry.io/otel/semconv/v1.41.0 package. The package contains semantic conventions from the v1.41.0 version of the OpenTelemetry Semantic Conventions. See the [migration documentation](https://link.gitcode.com/i/8ebaea2e8a7c31099d2317b907dcaf26) for information on how to upgrade from go.opentelemetry.io/otel/semconv/v1.40.0. (#8324)每个新版本子包还包含一份自动生成的 MIGRATION.md以 v1.40.0 → v1.41.0 为例它列出被移除的声明如DeploymentEnvironmentName并说明哪些属于官方弃用、哪些因缺乏用途被移除——这份迁移指南就是文档中Ensure things look correct before submitting a pull request所指的检查要点。2.2 更新代码库中的 semconv 导入生成新子包后必须把全仓库对旧版本的引用切到新版本。文档给出的典型 diff 如下// 修改前 semconv go.opentelemetry.io/otel/semconv/v1.37.0 go.opentelemetry.io/otel/semconv/v1.37.0/otelconv // 修改后 semconv go.opentelemetry.io/otel/semconv/v1.39.0 go.opentelemetry.io/otel/semconv/v1.39.0/otelconv在 Grafana Tempo 自身代码中同样能看到这种多版本 semconv 共存的情况例如 modules/generator/processor/servicegraphs/config.go 同时导入了semconv go.opentelemetry.io/otel/semconv/v1.25.0与semconvnew go.opentelemetry.io/otel/semconv/v1.34.0通过别名区分新旧属性——这正是文档update all semconv imports throughout the codebase在真实下游项目中的典型形态。替换完成后运行make全量编译与测试确认无破坏。2.3 属性变更的处理原则semconv 版本升级往往伴随着属性重命名、属性合并甚至属性值语义改变。文档给出的处理原则是优先迁移到替代旧属性的新属性保持与最新语义约定一致但对历史兼容场景仍可依据OTEL_SEMCONV_STABILITY_OPT_IN环境变量决定是否继续输出 legacy 属性复杂迁移的跟踪与执行可参考上游 issue #7806 的案例例如属性从http.*迁移到url.*这类大规模改名。2.4 联动更新 opentelemetry-go-contrib 的 lint 配置由于 contrib 仓库opentelemetry-go-contrib依赖主仓库的 semconv 版本文档要求同步更新其 .golangci.yml 中的 lint 规则强制 contrib 使用最新 semconv 版本避免两个仓库之间出现属性引用漂移。三、破坏性变更校验make goreleaseGo 的语义化版本承诺意味着公共 API 不能被无意修改。文档要求发布前运行make gorelease它底层调用golang.org/x/exp/cmd/gorelease工具逐模块对比当前代码与上次发布 tag 的公共 API 差异。从 Makefile 的实现看该目标遍历$(OTEL_GO_MOD_DIRS)中所有子模块目录并逐一执行 goreleasegorelease: $(OTEL_GO_MOD_DIRS:%gorelease/%) gorelease/%: DIR$* gorelease/%:| $(GORELEASE) echo gorelease in $(DIR): \ cd $(DIR) \ $(GORELEASE) \ || echo gorelease 会基于 go.mod 中的模块版本推断本次应该发布的主版本号检查是否存在不兼容的 API 变化并输出相应的版本号建议。它是发布前的公共 API 体检任何意外导出的符号删除、签名变更都会在这里暴露。文档同时提示gorelease 自身的问题可以反馈到 golang.org issue #26420。四、验证对 contrib 仓库的兼容性OTel 主仓库的变更往往会被opentelemetry-go-contrib消费。文档要求在发布前按照 contrib 仓库 RELEASING.md 中 Verify OTel changes 一节的操作验证主仓库改动与 contrib 的兼容性。这属于发布前的交叉验证环节主仓库是上游contrib 是最大的下游消费者两者版本必须同步演进否则会导致下游用户升级主库后 contrib 无法编译。五、Pre-Release确定模块集并准备发布分支5.1 模块集Module Set与 versions.yamlOTel Go 仓库包含数十个独立发布的 Go module如go.opentelemetry.io/otel、otel/metric、otel/sdk、各 exporters 子包等它们被组织成多个模块集每个模块集共享一个版本号。这一映射关系定义在仓库根目录的 versions.yaml 中当前仓库中实际存在四个模块集模块集版本当前仓库包含模块stable-v1v1.44.0go.opentelemetry.io/otel、otel/metric、otel/sdk、otel/trace、otel/exporters/otlp/*、otel/exporters/stdout/*、otel/exporters/zipkin、otel/bridge/*等experimental-metricsv0.66.0otel/exporters/prometheus、otel/metric/xexperimental-logsv0.20.0otel/log、otel/log/logtest、otel/sdk/log、otel/exporters/otlp/otlplog/*、otel/exporters/stdout/stdoutlogexperimental-schemav0.0.17otel/schema同时versions.yaml通过excluded-modules排除go.opentelemetry.io/otel/internal/tools等内部模块并通过version-refs将部分 exporter 的版本与内部internal/version.go文件挂钩确保版本号在生成代码中保持一致。当前仓库版本 v1.44.0/0.66.0/0.20.0/0.0.17 恰好对应 CHANGELOG 中最新发布条目四者一次发布完全符合文档描述的模块集机制。5.2 prerelease make 目标发布的第一步是在versions.yaml中更新目标模块集的新版本号并提交到新分支然后运行make prerelease MODSETmodule setMakefile 的实现显示prerelease先执行verify-mods即multimod verify再调用$(MULTIMOD) prerelease -m ${MODSET}prerelease: verify-mods [ ${MODSET} ] || ( echo env var MODSET is not set; exit 1 ) $(MULTIMOD) prerelease -m ${MODSET}其中MULTIMOD是go.opentelemetry.io/build-tools/multimod工具它是整个多模块版本管理的核心引擎。执行后会自动创建名为prerelease_module set_new tag的分支并把模块集中所有模块的 go.mod 版本统一改为新 tag。随后用git diff ...prerelease_module set_new tag核对所有模块版本是否都已正确更新确认无误后合并进预发布分支git merge prerelease_module set_new tag5.3 更新 CHANGELOG文档要求把预发布分支中的 CHANGELOG.md 整理为正式发布形态用git --no-pager log --prettyoneline last tag..HEAD检查上次 tag 以来的全部提交确保没有遗漏变更将所有Unreleased变更移入新章节标题遵循[new tag] - date of release格式例如仓库中的## [1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27新章节必须放在!-- Released section --注释之下以便被发布脚本保护、防止未来被误改更新文末的所有版本链接。这里值得展开说明Released section注释的作用仓库根目录的 verify_released_changelog.sh 脚本专门用于保证已发布章节不被篡改——它会从目标分支检出上一版本的 CHANGELOG用awk /^!-- Released section --/ {flag1} /^!-- Released section ended --/ {flag0}分别提取新旧文件的已发布区块并 diff一旦发现差异立即以非零状态退出false。这与 CHANGELOG.md 中!-- Released section --与!-- Released section ended --标记的实际位置一一对应。也就是说发布一旦完成历史章节即被锁死任何后续 PR 都不得回改已发布内容——这是保证发布记录不可变审计链的工程手段。推送并创建 Pull RequestPR 描述中必须附带整理好的 Changelog 内容。六、Tag为合并提交打上版本标签PR 合并到主干后进入打 tag 阶段。文档用两个加粗的 IMPORTANT 强调了其严肃性必须使用与 Pre-Release 阶段完全相同的 tag否则系统会处于 broken 状态只要在两步之间不修改versions.yaml版本就不会错位。Go module 的 tag 一旦打错就无法删除见 golang issue #34189错误的 tag 会引发下游用户的紧急事故见 opentelemetry-go issue #331因此推送前必须反复确认版本号。操作命令make add-tags MODSETmodule set COMMITcommit hashMakefile 的实现为COMMIT ? HEAD add-tags: verify-mods [ ${MODSET} ] || ( echo env var MODSET is not set; exit 1 ) $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}COMMIT默认为当前HEAD仅当本地 HEAD 不是合并提交时才需要显式传值。打 tag 完成后需要把主模块与所有子模块的 tag 全部推送到上游注意是官方仓库github.com/open-telemetry/opentelemetry-go.git不是自己的 forkgit push upstream new tag git push upstream submodules-path/new tag ...这正是versions.yaml中每个子模块如otel/exporters/otlp/otlptrace/otlptracegrpc都需要独立 tag 的原因——Go module proxy 要求每个 module 的版本对应一个独立的 tag 路径。七、签名发布工件Sign artifacts为符合 CNCF 最佳实践发布工件必须用 GPG 签名。文档给出的步骤是从 GitHub tags 页面下载新 tag 对应的.tar.gz与.zip两份归档签名前可用 attest-sh 脚本核验归档内容用gpg --list-secret-keys --keyid-formatlong获取密钥 ID即sec rsa4096/之后的 16 位字符串设置环境变量并分别签名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签名的作用是让下游用户和供应链安全工具能够验证归档文件的完整性与发布者身份这是 CNCF 项目中软件供应链安全SLSA/签名校验实践的一部分。八、发布 GitHub Release在 GitHub 上为new tag创建 Release正文必须包含该版本的完整 Changelog 内容。文档特别强调GitHub Releases 一旦创建即不可变必须在创建时就把已签名的四个工件.tar.gz、.tar.gz.asc、.zip、.zip.asc一并上传之后无法补充或修改。这一约束把签名与上传两个动作绑定在同一时刻杜绝了先发不带签名的包、事后补签的供应链风险。九、Post-Release 收尾发布不是终点文档列出了四项收尾工作9.1 Contrib 仓库联动发布确认主仓库发布无误后按 contrib 仓库的 RELEASING.md 流程发布基于该版本的上游 contrib 版本保证贡献库的用户也能拿到新能力。9.2 官方文档更新更新 OpenTelemetry 官网content/en/docs/languages/go下的 Go instrumentation 文档重点是把文档中引用的包版本 bump 到刚发布的版本并确保所有代码示例仍然可编译、准确。9.3 关闭 Milestone把所有本次发布修复的 issue 和合并的 PR 归入对应 milestone然后关闭 milestone。文档给出了两个辅助搜索查找未归入 milestone 的已关闭 issue使用is:issue no:milestone is:closed ... linked:pr查询查找未归入 milestone 的已合并 PR使用is:pr no:milestone is:merged查询。这保证了版本变更的可追溯性——每个修复都能追溯到它属于哪个发布版本。9.4 关闭 Version Release Issue当 Version Release issue 中的 todo list 全部完成从语义约定升级、预发布、打 tag、签名、发布到 milestone 收尾关闭该 issue一次完整的发布流程即告结束。十、发布流程全景与 Tempo 仓库的对应关系将以上阶段串联起来一次 OTel Go 发布的生命周期为创建 Version Release issue → semconv 升级semconv-generate 更新导入 更新 contrib lint → make gorelease 校验公共 API → 验证 contrib 兼容性 → Pre-Releaseversions.yaml make prerelease CHANGELOG → Tagmake add-tags 推送所有子模块 tag → GPG 签名归档 → 创建 GitHub Release上传签名工件 → Post-Releasecontrib 发布 官网文档 关闭 milestone 关闭 issue对于 Grafana Tempo 而言其 go.mod 中锁定go.opentelemetry.io/otel v1.44.0、go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0、otlptracehttp v1.44.0等版本全部落在stable-v1模块集的统一版本下同时 Tempo 自身的 metrics-generator如 servicegraphs 处理器同时使用 v1.25.0 与 v1.34.0 两代 semconv 子包——这既是本文所述 semconv 子包独立版本策略的直接体现也说明下游项目可以按需引用多个语义约定版本。理解这套发布流程不仅有助于 OTel Go 生态的贡献者参与发布也能帮助所有 Go 多模块项目的维护者设计自己的版本发布工程。需要说明的是本文中涉及的 OTel 版本号、模块集划分与 semconv 子包列表均以当前 Tempo 仓库 vendor 目录中锁定的内容为准若以其他版本为发布目标请以当时仓库实际的versions.yaml、CHANGELOG.md与 Makefile 为准。发布操作请在 OTel Go 官方仓库非 Tempo 仓库的维护流程中进行本仓库仅作为文档与依赖的只读样例。赞分享后端可观测性链路追踪【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址https://gitcode.com/GitHub_Trending/tempo1/tempo点击查看免费下载相关推荐OpenTelemetry Go SDK 版本发布全流程指南从语义约定升级、多模块打标签到 GPG 签名与收尾OpenTelemetry Go SDK 版本发布全流程指南从语义约定升级、多模块打标签到 GPG 签名与收尾 本指南以 OpenTelemetry Go S云原生CLI镜像仓库OpenTelemetry Go 多模块版本发布流程深度指南从 semconv 升级、模块集打 tag 到 GPG 签名OpenTelemetry Go 多模块版本发布流程深度指南从 semconv 升级、模块集打 tag 到 GPG 签名 本文以当前仓库 vendored 的云原生容器编排集群管理微服务OpenTelemetry Go SDK 发布流程实战指南从语义约定升级到 GPG 签名发布OpenTelemetry Go SDK 发布流程实战指南从语义约定升级到 GPG 签名发布 本指南以本仓库中随依赖一并 vendored 的 vendor/后端任务调度工作流自动化微服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考