OpenTelemetry Go is a multi-module repository, but GitHub Releases currently present each coordinated release as one combined release. This makes releases hard to use from a Go user's perspective.
Users usually do not ask "what changed anywhere in this repository?" They ask:
- "I use
go.opentelemetry.io/otel/sdk/metric; what changed for that module?"
- "What version of this module contains a fix?"
- "What version do I need for this feature?"
- "Which module versions are intended to be used together?"
Outside of the last question, the current combined release notes make those answers harder to find. They also produce large, noisy release notes that include changes unrelated to the module a user depends on.
At the same time, the current versioning policy is important and should be preserved. Stable modules intentionally share the same full version, and unchanged modules may be released to keep versions aligned. This proposal is about changing release presentation and tooling, not changing the versioning policy.
Goals
- Publish GitHub Release pages that are directly addressable by Go module path and version, using titles like
go.opentelemetry.io/otel/sdk/metric@v1.45.0.
- Keep the root stable release,
go.opentelemetry.io/otel@v1.45.0, as the repo-level Latest release and compatibility entry point.
- Preserve the existing versioning policy in
VERSIONING.md.
- Keep one combined root
CHANGELOG.md in Keep a Changelog format.
- Generate module-specific GitHub release notes from structured fragments.
- Reduce maintainer release overhead through automation.
- Replace manual GPG artifact signing with automated
cosign signing.
- Keep release publication reviewable by maintainers before users are notified.
Non-Goals
- Do not change the OpenTelemetry Go versioning policy.
- Do not stop tagging aligned modules in phase one.
- Do not backfill historical module-specific GitHub Releases.
- Do not introduce per-module milestones in phase one.
- Do not replace Go module tooling with a custom public release manifest.
Proposal
GitHub Releases
For each pushed module tag, create a GitHub Release.
Release titles should use Go module syntax:
go.opentelemetry.io/otel@v1.45.0
go.opentelemetry.io/otel/sdk/metric@v1.45.0
go.opentelemetry.io/otel/exporters/prometheus@v0.67.0
Only the root stable release should be marked as GitHub's Latest release. All module-path releases should use latest=false.
The root stable release body should act as the compatibility entry point. It should include a concise table of module sets and versions released together, then only the root/stable notes directly relevant to go.opentelemetry.io/otel.
Module releases should contain module-specific notes first. If a module has no direct user-facing changes, create a minimal release body explaining that it was released for version alignment.
Example minimal body:
This module was released as part of the OpenTelemetry Go v1.45.0 coordinated release.
There are no direct user-facing changes for `go.opentelemetry.io/otel/sdk/trace` in this release. The tag is published to keep module versions aligned according to the project versioning policy.
For compatibility context and links to related module releases, see `go.opentelemetry.io/otel@v1.45.0`.
Release Notes
Move normal PRs away from editing CHANGELOG.md directly. Instead, use release-note fragments for user-facing changes.
Fragments should use Keep a Changelog categories:
added
changed
deprecated
removed
fixed
security
Breaking changes should be represented as metadata on entries, for example:
category: changed
breaking: true
note: The default metric cardinality limit is now 2000.
Rendered output should preserve the current style:
### Changed
- Warning: **Breaking Change:** The default metric cardinality limit is now 2000.
Each fragment should normally represent one public changelog entry. If a PR has multiple unrelated public changes, it should use multiple fragment files rather than one broad entry.
Module Targeting
Fragments should record note_modules: the modules whose user-facing behavior, API, docs, configuration, or telemetry are directly affected.
Tooling should infer suggested module metadata from:
- changed paths mapped to nearest
go.mod,
- repo module relationships,
- release-note context,
- maintainer edits.
Dependency propagation should affect release planning, not release-note duplication.
In other words:
note_modules: where the note appears.
release_modules: modules that need tags/releases for version alignment or dependency closure.
release_modules should be computed by tooling, with optional overrides for unusual cases such as module splits, retractions, or dependency-only security updates.
CHANGELOG.md
Keep one root CHANGELOG.md as the combined project changelog.
It should continue to use Keep a Changelog format. The current version-combination headings can remain, but generated sections should include a clearer context sentence.
Example:
## [1.45.0/0.67.0/0.21.0/0.0.18] 2026-06-04
This coordinated release includes stable-v1 v1.45.0, experimental-metrics v0.67.0, experimental-logs v0.21.0, and experimental-schema v0.0.18.
Reference links at the bottom should continue if practical, but tooling should own them.
chloggen
chloggen is the preferred implementation path because OpenTelemetry controls it and it already supports fragment-based changelog generation.
However, chloggen needs updates before it can support this workflow. Blockers include:
- Keep a Changelog category support.
- Module-aware release-note metadata.
- Generation of both combined
CHANGELOG.md output and module-specific GitHub release bodies.
- Support for bot/tool-assisted module metadata.
If extending chloggen turns out awkward, the requirements above should guide an alternate implementation.
Release Automation
Draft GitHub Releases should be created automatically after tags are pushed, once per release wave rather than once per tag.
For normal stable releases, the workflow can key off the root stable tag. Non-stable-only releases should be supported through manual workflow dispatch.
Draft creation and publication must be separate steps. Automation should create draft releases and upload assets. A maintainer should then explicitly run a separate publish job after review.
The publish job should derive the release set from versions.yaml and tags. It should not require a checked-in public release manifest. Ephemeral workflow artifacts are fine as implementation details.
Artifacts and Signing
Phase one should automate signed canonical source artifacts for every generated GitHub Release.
The workflow should:
- create canonical
.tar.gz and .zip archives for each release tag,
- upload them as release assets,
- generate checksums,
- sign artifacts/checksums with keyless
cosign,
- upload verification bundles,
- avoid relying on GitHub's automatically generated source archive links as the signed artifacts.
This removes manual GPG signing burden while preserving signed release assets.
Suggested Rollout
- Ship the current accumulated
CHANGELOG.md Unreleased section using the existing release process.
- Land fragment-based release-note tooling immediately after that release.
- Replace the current changelog CI check with a fragment-aware check.
- Require fragments for new user-facing PRs, or an explicit
Skip Changelog/equivalent marker.
- Update
chloggen or equivalent tooling to generate:
- combined
CHANGELOG.md,
- root stable release body,
- module-specific release bodies.
- Add automated draft release creation with signed artifacts.
- Add a separate maintainer-triggered publish workflow.
- Use the new module-specific release workflow for the following release.
Success Criteria
- Users can find module-specific release notes by searching for
module@version.
- The root stable release shows compatible module-set versions without duplicating all module notes.
- Modules with no direct user-facing changes have concise release pages explaining version alignment.
- Normal PR authors no longer edit
CHANGELOG.md directly.
CHANGELOG.md remains generated in Keep a Changelog format.
- Maintainers no longer manually sign artifacts with GPG.
- Draft releases are reviewable before publication.
- The existing
VERSIONING.md policy remains intact.
Future Work
- Consider selective tagging once per-module version state and dependency-closure tooling exist.
- Consider per-module or MODSET-specific milestones if release planning needs them.
- Consider a public machine-readable release manifest if real user or automation demand appears.
- Consider auto-publishing after the draft workflow has proven reliable.
OpenTelemetry Go is a multi-module repository, but GitHub Releases currently present each coordinated release as one combined release. This makes releases hard to use from a Go user's perspective.
Users usually do not ask "what changed anywhere in this repository?" They ask:
go.opentelemetry.io/otel/sdk/metric; what changed for that module?"Outside of the last question, the current combined release notes make those answers harder to find. They also produce large, noisy release notes that include changes unrelated to the module a user depends on.
At the same time, the current versioning policy is important and should be preserved. Stable modules intentionally share the same full version, and unchanged modules may be released to keep versions aligned. This proposal is about changing release presentation and tooling, not changing the versioning policy.
Goals
go.opentelemetry.io/otel/sdk/metric@v1.45.0.go.opentelemetry.io/otel@v1.45.0, as the repo-levelLatestrelease and compatibility entry point.VERSIONING.md.CHANGELOG.mdin Keep a Changelog format.cosignsigning.Non-Goals
Proposal
GitHub Releases
For each pushed module tag, create a GitHub Release.
Release titles should use Go module syntax:
Only the root stable release should be marked as GitHub's
Latestrelease. All module-path releases should uselatest=false.The root stable release body should act as the compatibility entry point. It should include a concise table of module sets and versions released together, then only the root/stable notes directly relevant to
go.opentelemetry.io/otel.Module releases should contain module-specific notes first. If a module has no direct user-facing changes, create a minimal release body explaining that it was released for version alignment.
Example minimal body:
Release Notes
Move normal PRs away from editing
CHANGELOG.mddirectly. Instead, use release-note fragments for user-facing changes.Fragments should use Keep a Changelog categories:
addedchangeddeprecatedremovedfixedsecurityBreaking changes should be represented as metadata on entries, for example:
Rendered output should preserve the current style:
Each fragment should normally represent one public changelog entry. If a PR has multiple unrelated public changes, it should use multiple fragment files rather than one broad entry.
Module Targeting
Fragments should record
note_modules: the modules whose user-facing behavior, API, docs, configuration, or telemetry are directly affected.Tooling should infer suggested module metadata from:
go.mod,Dependency propagation should affect release planning, not release-note duplication.
In other words:
note_modules: where the note appears.release_modules: modules that need tags/releases for version alignment or dependency closure.release_modulesshould be computed by tooling, with optional overrides for unusual cases such as module splits, retractions, or dependency-only security updates.CHANGELOG.mdKeep one root
CHANGELOG.mdas the combined project changelog.It should continue to use Keep a Changelog format. The current version-combination headings can remain, but generated sections should include a clearer context sentence.
Example:
## [1.45.0/0.67.0/0.21.0/0.0.18] 2026-06-04 This coordinated release includes stable-v1 v1.45.0, experimental-metrics v0.67.0, experimental-logs v0.21.0, and experimental-schema v0.0.18.Reference links at the bottom should continue if practical, but tooling should own them.
chloggenchloggenis the preferred implementation path because OpenTelemetry controls it and it already supports fragment-based changelog generation.However,
chloggenneeds updates before it can support this workflow. Blockers include:CHANGELOG.mdoutput and module-specific GitHub release bodies.If extending
chloggenturns out awkward, the requirements above should guide an alternate implementation.Release Automation
Draft GitHub Releases should be created automatically after tags are pushed, once per release wave rather than once per tag.
For normal stable releases, the workflow can key off the root stable tag. Non-stable-only releases should be supported through manual workflow dispatch.
Draft creation and publication must be separate steps. Automation should create draft releases and upload assets. A maintainer should then explicitly run a separate publish job after review.
The publish job should derive the release set from
versions.yamland tags. It should not require a checked-in public release manifest. Ephemeral workflow artifacts are fine as implementation details.Artifacts and Signing
Phase one should automate signed canonical source artifacts for every generated GitHub Release.
The workflow should:
.tar.gzand.ziparchives for each release tag,cosign,This removes manual GPG signing burden while preserving signed release assets.
Suggested Rollout
CHANGELOG.mdUnreleasedsection using the existing release process.Skip Changelog/equivalent marker.chloggenor equivalent tooling to generate:CHANGELOG.md,Success Criteria
module@version.CHANGELOG.mddirectly.CHANGELOG.mdremains generated in Keep a Changelog format.VERSIONING.mdpolicy remains intact.Future Work