112 lines
5.5 KiB
Markdown
112 lines
5.5 KiB
Markdown
# 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.
|