Accept ADR 0005 for module-scoped releases

This commit is contained in:
2026-10-09 16:15:54 +00:00
parent e43df4416e
commit 86c1da2cf5

View File

@@ -0,0 +1,111 @@
# ADR 0005: Select a Go module as the unit of release
## Status
Accepted.
## Date
2026-10-09
## Context
A Go repository can contain independently versioned modules. CommandKit plans
to release its core and optional integrations from one repository. Each module
needs its own validation, release note, semantic version, and Git tag.
ReleaseKit currently couples the semantic version to the Git tag and uses the
repository directory for Go validation and release-note discovery. Supporting
independent modules through consumer-owned publication code would duplicate
ReleaseKit's responsibilities.
[ADR 0002](0002-routine-releases.md) prioritizes routine releases with little
application-owned code or recurring decision-making.
[ADR 0003](0003-declarative-validation.md) establishes shared declarative
validation. Module selection should give those checks a coherent release scope.
## Decision
Each check or publication invocation selects one Go module within a Git
repository. Omitted module selection means the repository-root module. The
public Go API and CLI/profile interface express the same selection. Consumers
can use small per-module profiles through a shared launcher.
ReleaseKit distinguishes the repository directory, selected module directory,
semantic version, and complete Git tag. It derives the tag using Go's module
tag conventions and the selected module's committed declaration. Derivation
accounts for major-version directories. For example, a module in
`integrations/ckconfig` at `v0.2.0` uses the tag
`integrations/ckconfig/v0.2.0`. A module declared with a `/v2` suffix and stored
in `integrations/ckconfig/v2` uses `integrations/ckconfig/v2.0.0` for `v2.0.0`.
The semantic version identifies the module release. The complete tag identifies
its source in the shared repository and governs uniqueness, tag creation,
publication, source links, and recovery. Candidate evidence, publication
results, and CLI output identify the selected module and both version and tag,
alongside the existing commit and publication evidence. Failure outcomes retain
the resolved identity for recovery.
Release notes belong at `<module-directory>/docs/releases/<version>.md` and
identify the product and semantic version in their title. ReleaseKit reads the
selected note from the captured candidate. Root-module releases retain the
existing note layout and unprefixed tags. Modules can publish equal semantic
versions through their distinct notes and tags.
Mandatory and optional release validation share the selected module's scope.
Go tests, selected vet, and package compilation execute in that module with
the existing offline environment. File checks inspect the module's committed
contents and relevant release materials. Independently released nested modules
are excluded from their parent's validation scope. Selecting the root module
follows the same rule.
A check may inspect referenced material outside the selected module when needed
to validate an in-scope item. Resolving a Markdown link to shared repository
documentation does not add that destination's documents to the validation input
set. The checkout remains the boundary for checks of outside-checkout links.
Shared release materials follow established conventions and documented
consumer requirements.
Product-specific checks receive the selected module context and repository
context for deliberate composition checks. ReleaseKit applies module selection
consistently across its shared checks, avoiding separate scope settings for
each check.
Publication guards cover the shared repository: cleanliness, branch, candidate
commit, authoritative endpoint, and the complete selected tag. The standard
suite runs once for the selected candidate and module. Successful source-tag
publication remains the completion point, with existing failure and uncertain
publication outcomes preserved. Consumers prepare released sibling dependencies
and choose their publication order.
## Alternatives considered
- Consumer-owned module publication gives each application responsibility for
tag conventions, validation, and recovery, duplicating shared mechanics.
- Module-local Go execution with repository-wide optional validation lets
unrelated modules block a selected release and gives checks inconsistent
scopes.
- Independent scope settings for each check require consumers to coordinate
multiple declarations of the same release boundary.
- Coordinated multi-module publication adds release-set and dependency-ordering
responsibilities beyond the demonstrated need for individual releases.
## Consequences
Consumers describe the module and product being released while ReleaseKit owns
the common procedure. Existing single-module repositories retain their default
behavior. Root modules containing independently released nested modules gain
module-scoped validation; release notes and migration guidance must explain
that change.
The shared candidate and publication paths must carry module scope and separate
version and tag identity throughout validation, diagnostics, and recovery.
Verification must cover root defaults, nested-module failures, equal versions
across modules, major-version directories, validation boundaries, and exact-tag
publication outcomes.
GoDoc and consumer documentation will own exact API and scope contracts.
Configuration and CLI documentation will own profile fields, commands, and
output. Implementation planning will define interactions with artifact builds
and hosted delivery. ReleaseKit's maintainer release policy continues to govern
ReleaseKit's own releases; consumers document their adopted module conventions.