336 lines
18 KiB
Markdown
336 lines
18 KiB
Markdown
# Roadmap: release individual Go modules
|
|
|
|
Status: implemented; post-implementation findings and corrections are recorded
|
|
in the [remediation review](remediation.md). Release version remains unselected.
|
|
|
|
## Purpose
|
|
|
|
Implement [ADR 0005](../adr/0005-module-release-scope.md) so a consumer can check,
|
|
publish, build, and deliver one selected Go module in a shared repository through
|
|
ReleaseKit's API and CLI. CommandKit's core and optional integrations provide the initial
|
|
consumer case. Each invocation should require only module selection, product
|
|
settings, and a semantic version, with ReleaseKit owning the common mechanics.
|
|
|
|
This roadmap records the feature's target and resolved scope and ownership
|
|
decisions. The [implementation plan](implementation.md) records the completed
|
|
stages; [remediation](remediation.md) records review corrections. Current behavior
|
|
belongs in the [consumer guides](../consumers/), [CLI](../cli.md),
|
|
[configuration](../config.md), and facade GoDoc.
|
|
|
|
## Historical starting baseline
|
|
|
|
Work started from ReleaseKit v0.3.0 plus accepted ADR 0005. At that starting
|
|
point, module selection was unimplemented and the following baseline applied.
|
|
|
|
- `ReleaseRequest` selects a repository, product, and version. `Candidate` and
|
|
`PublicationResult` expose the version without a distinct module or tag name.
|
|
- Candidate capture reads `docs/releases/<version>.md` from the captured commit.
|
|
Local and remote uniqueness checks, tag creation, push, and reconciliation use
|
|
the version as the Git tag.
|
|
- The shared validation path runs tests, selected vet, and package compilation
|
|
from the repository directory. Optional content checks inspect the committed
|
|
repository tree, including nested-module contents.
|
|
- Profiles support shared validation and additional commands. CLI product
|
|
checks run from the repository directory with candidate/version context.
|
|
- Artifact builds and delivery also use repository/version assumptions. The
|
|
consumer Woodpecker template selects `refs/tags/v*` and bootstraps ReleaseKit
|
|
from repository-root module files.
|
|
|
|
Candidate capture, declarative validation, exact-object publication, and outcome
|
|
reporting provided the foundation for carrying scope and identity through all
|
|
operations.
|
|
|
|
## Targeted end state
|
|
|
|
An invocation selects one module and one semantic version. Omitted selection
|
|
means the repository-root module. For example:
|
|
|
|
| Selected directory | Semantic version | Complete tag | Committed release note |
|
|
| --- | --- | --- | --- |
|
|
| Root | `v0.1.0` | `v0.1.0` | `docs/releases/v0.1.0.md` |
|
|
| `integrations/ckconfig` | `v0.2.0` | `integrations/ckconfig/v0.2.0` | `integrations/ckconfig/docs/releases/v0.2.0.md` |
|
|
| `integrations/ckprompt` | `v0.1.0` | `integrations/ckprompt/v0.1.0` | `integrations/ckprompt/docs/releases/v0.1.0.md` |
|
|
|
|
All mandatory and selected optional release checks use the selected module's
|
|
scope. Independently released nested modules are excluded from their parent's
|
|
automatic validation inputs. Shared file selections follow the
|
|
[resolved shared-file rules](#shared-file-validation-inputs). Checks may read
|
|
referenced material elsewhere in the captured repository without adding that
|
|
material's surrounding files to the input set. The checkout remains the boundary for outside-checkout link checks.
|
|
|
|
Repository cleanliness, branch, candidate commit, remote endpoint, and publication
|
|
guards remain repository-wide. The complete selected tag governs uniqueness,
|
|
publication, and recovery. A successful source-tag push remains completion.
|
|
Consumers prepare dependencies before offline candidate validation and choose
|
|
sibling release ordering. Dependency preparation for delivery targets the
|
|
selected module through the existing preparation operation when needed.
|
|
|
|
The feature covers individual releases. Batch publication, automatic release
|
|
selection, dependency-driven versioning, and arbitrary tag templates remain
|
|
outside this roadmap. Artifact builds, hosted delivery, and CI use the same
|
|
selected module and release identity. Delivery remains asynchronous and supports
|
|
both page-only and binary profiles. This work adds no consumer-installation,
|
|
proxy-availability, CI, or hosted-delivery publication completion gate.
|
|
|
|
## Capability requirements
|
|
|
|
### Module and release identity
|
|
|
|
Repository directory, physical module directory, declared module path, semantic
|
|
version, and complete Git tag are distinct and available throughout operations
|
|
and public evidence. Shared derivation follows standard Go conventions, including
|
|
major-version layouts with and without a physical major directory. A `/v2`
|
|
module at either `integrations/ckconfig` or `integrations/ckconfig/v2` uses
|
|
`integrations/ckconfig/v2.0.0` for `v2.0.0`. Failure evidence retains resolved
|
|
identity alongside existing commit, endpoint, phase, state, and tag-object fields
|
|
as available. Facade conversions preserve underlying causes.
|
|
|
|
### Coherent validation scope
|
|
|
|
Tests, vet, and package compilation execute in the selected module with offline
|
|
and workspace-disabled settings. Formatting, distribution checks, file size,
|
|
and Markdown share ordered committed module and selected shared-file inputs.
|
|
Product checks receive the selected module's context. File checks retain complete
|
|
repository lookup for targeted reference reads. Existing optional check rules,
|
|
error identities, cancellation, and causes apply within that scope.
|
|
|
|
### Notes, publication, and recovery
|
|
|
|
Each module's committed note identifies its product and semantic version at
|
|
its module-local note path. Local and remote uniqueness, annotated tag creation,
|
|
exact-object push, and bounded reconciliation address the complete tag.
|
|
Repository-wide guards and publication outcomes remain in place. Different
|
|
modules can use equal semantic versions with distinct notes and tags.
|
|
|
|
### Builds, receipts, and hosted delivery
|
|
|
|
Standalone builds, candidate build checks, managed delivery builds, and prebuilt
|
|
delivery use the selected module. Module-owned execution and output paths use
|
|
that module's directory. Binaries report semantic versions; hosted pages and
|
|
source links use full tags and module-local notes. Builds and receipts carry
|
|
module and source evidence. Delivery validates that evidence and actual artifact
|
|
content before hosted requests, retaining page/asset conflicts, additive retries,
|
|
and partial outcomes. Page-only profiles require no application binary or
|
|
Go environment discovery.
|
|
|
|
### CLI and module-selected CI
|
|
|
|
Profiles express the API's module and shared-file selections through existing
|
|
profile lookup. Product commands receive both module and repository context.
|
|
A small shared launcher selects profiles and semantic versions. Mapped CI
|
|
selects the physical module and profile from the verified tagged checkout before
|
|
bootstrapping its selected tool. Local launchers and CI share one consumer
|
|
selection declaration. ReleaseKit verifies selection against derived identity.
|
|
Root-only consumers retain default bootstrap and profile behavior without a map.
|
|
Retries use the original tagged source's selection and tool configuration.
|
|
|
|
### Complete adoption guidance and behavioral evidence
|
|
|
|
Canonical API, CLI, configuration, consumer, integration, and recovery documents
|
|
and maintained examples describe the complete interface. The next release's
|
|
migration guidance covers API and profile updates, receipt regeneration, CI
|
|
selection, and root-module scope changes, including nested fixture modules.
|
|
Focused owner tests and representative assembled workflows establish the target
|
|
behavior with local repositories, HTTP fixtures, and isolated synthetic dependency
|
|
caches. The [implementation plan](implementation.md#acceptance-coverage-audit)
|
|
owns the concrete acceptance coverage and execution steps.
|
|
|
|
## Resolved decisions
|
|
|
|
### Resolve identity once
|
|
|
|
Each ReleaseKit operation resolves repository directory, selected module
|
|
directory and declaration, semantic version, and complete tag once through
|
|
shared resolution logic. Pass that identity through candidate handling,
|
|
validation, callbacks, publication, builds, receipts, delivery, and evidence.
|
|
Subsystems consume the resolved module and tag. Repository-state, tagged-source,
|
|
and artifact verification continue against that identity through their existing
|
|
guards.
|
|
|
|
### Operation prerequisites and identity
|
|
|
|
Shared resolution supplies module and tag identity to each operation.
|
|
Candidate checking and publication retain clean source on the primary branch,
|
|
committed release notes, and their existing unused-tag checks. Delivery
|
|
retains clean tagged-source verification and supports historical releases and
|
|
detached checkouts. Ordinary builds retain their support for modified source
|
|
and operate independently of release-note and publication prerequisites.
|
|
|
|
Composite operations pass resolved identity to their internal collaborators.
|
|
Standalone operations use the same resolver at entry, with declaration source
|
|
selected by the operation as described below.
|
|
|
|
### Declaration source by operation
|
|
|
|
Candidate checks, publication, and tagged delivery resolve identity from
|
|
committed module declarations. Standalone builds read the selected module's
|
|
working-tree `go.mod`, so their identity corresponds to the declaration Go
|
|
uses for compilation. This supports local development of changed module paths
|
|
and new module directories before commit.
|
|
|
|
The operation selects the declaration source and uses shared identity derivation
|
|
logic. Composite candidate and delivery builds receive their already resolved
|
|
committed identity. Existing source-verification observations remain in place;
|
|
delivery requires a build verified against its committed tagged source.
|
|
|
|
### One validation input set and full repository lookup
|
|
|
|
Construct file inputs when enabled checks or explicit shared-file validation
|
|
need them. Compute module boundaries and the ordered, deduplicated input set
|
|
once using committed metadata. File checks consume that set. Keep the full
|
|
repository lookup available for targeted reads and reference resolution, with scoped reader
|
|
ownership and cancellation preserved.
|
|
|
|
Deduplicate inputs by path. Reuse parsed results by blob identity while retaining
|
|
each source path's findings and relative destinations. This preserves the
|
|
existing selective caches and avoids retaining all inspected raw content.
|
|
|
|
### Version and tag boundaries
|
|
|
|
Keep semantic version and complete tag distinct in internal requests and evidence.
|
|
Version injection, artifact filenames, smoke checks, and note titles use the
|
|
semantic version. Git publication, recovery, and hosted release identity use
|
|
the complete tag. URL construction belongs to each protocol owner, which encodes
|
|
the literal tag for its route. Verify slash-containing tags in API and source
|
|
links.
|
|
|
|
### Failure evidence
|
|
|
|
Populate available module, version, tag, and commit evidence as resolution
|
|
progresses. Later failures retain that evidence alongside the operation's
|
|
existing phase, endpoint, tag-object, and outcome fields as available. Shared
|
|
facade conversions preserve these fields and the underlying error causes.
|
|
|
|
### Go environment ownership
|
|
|
|
Lazily discover effective Go settings for the selected module and reuse them
|
|
within the operation's validation and build phases when environment inputs are
|
|
unchanged. Ownership and reuse are operation-local. Dependency preparation keeps
|
|
its separate network-capable environment. Page-only delivery retains its path
|
|
without Go-tool discovery or application dependency preparation.
|
|
|
|
### Build settings, receipts, and asset verification
|
|
|
|
Normalize build settings once and reuse that representation for execution,
|
|
receipt binding, and comparisons. The new receipt format binds module identity
|
|
alongside existing source and artifact evidence. Loading validates structure,
|
|
identity, and file declarations. Delivery owns the content-verification pass
|
|
before hosted requests, for both API and CLI callers.
|
|
|
|
Build-time hashing records the produced bytes; delivery-time verification
|
|
establishes that the selected files still match them. Candidate and managed
|
|
delivery output stays outside the whole repository. Ordinary output paths use
|
|
the selected module's path base.
|
|
|
|
### CI bootstrap and checkout ownership
|
|
|
|
For module-mapped workflows, use one small committed consumer selection
|
|
declaration shared by the launcher and CI. Bootstrap verifies the triggering
|
|
tag and commit, selects the physical module and profile, and builds the tool
|
|
from that module's configuration. ReleaseKit verifies selection against the
|
|
derived identity.
|
|
|
|
The workflow prepares the checkout before tool bootstrap. Subsequent delivery
|
|
reuses that checkout with fresh read-only source checks. Standalone CI delivery
|
|
performs preparation when needed. Share verification behavior across these
|
|
entry paths, keeping root defaults and tagged-source selection on retries.
|
|
|
|
### Simple single-module experience
|
|
|
|
Ordinary root-module consumers use the new interface's defaults: omitted module
|
|
selection means the repository root, the complete tag equals the semantic
|
|
version, notes use `docs/releases/<version>.md`, and validation and builds run
|
|
from the root module. Shared-file defaults apply with input deduplication.
|
|
Root-tag CI uses the ordinary profile and repository-root tool bootstrap.
|
|
|
|
Routine use requires no additional configuration fields, module mapping
|
|
declarations, or recurring consumer decisions. A representative root-module
|
|
profile, launcher, and CI workflow remain equally small after migration.
|
|
Consumers supply their existing product facts through the new interface.
|
|
One-time API updates and receipt regeneration belong in the next release's
|
|
migration guidance under the clean-cutover decision below.
|
|
|
|
### Module boundaries
|
|
|
|
Use committed nested `go.mod` locations as module boundaries for ordinary source
|
|
directories. This follows Go's module structure and avoids a second registry of
|
|
independently versioned products. Vendored material remains part of the selected
|
|
module's file-check inputs. Nested fixture modules are excluded from automatic
|
|
parent file checks and can be exercised through the parent's tests or product
|
|
checks. Document this distinction and verify representative cases.
|
|
|
|
A repository-level workspace file outside the selected nested module's scope
|
|
does not fail that module's workspace-file check merely because it exists.
|
|
Shared release materials and referenced destinations receive the targeted
|
|
inspection described above.
|
|
|
|
### Shared file-validation inputs
|
|
|
|
Provide an optional shared-file list in the public request and profile. Its
|
|
selection applies only to shared file-validation inputs. Existing validation
|
|
selections control which checks are enabled. Enabled checks retain their rules,
|
|
and Go tests, vet, and package compilation retain the selected module's scope.
|
|
|
|
| Selection | Shared files added automatically |
|
|
| --- | --- |
|
|
| Omitted list | Repository-root `COPYRIGHT`, `LICENSE`, and `docs/oss/attribution.md`, when present. |
|
|
| Explicit list | The listed files replace the defaults. |
|
|
| Explicit empty list | No shared files. |
|
|
|
|
In Go, a nil slice selects the defaults; a non-nil empty slice selects none.
|
|
In JSON, omission or `null` selects the defaults; `[]` selects none. Preserve
|
|
this distinction through profile mapping and facade conversions, including
|
|
slice copying and profile serialization. Resolve the defaults once. Exact field
|
|
names belong in API design.
|
|
|
|
Paths are repository-relative literal file paths. This initial selection
|
|
supports individual files. Resolve presence and file identity from the captured
|
|
committed tree. Missing explicitly selected files produce a configuration or
|
|
validation error identifying the selected path, including when optional file
|
|
checks are disabled. Defaults are optional when absent.
|
|
|
|
Deduplicate the combined module and shared-file inputs by committed path, so a
|
|
file already in module scope or repeated in the list is checked once. Explicit
|
|
selection may name a file in another module; include that file alone. Reference
|
|
resolution continues to inspect destinations using existing rules and leaves
|
|
those destinations outside the input set unless independently selected.
|
|
|
|
### Relative paths and product commands
|
|
|
|
Anchor module selection and profile lookup at the repository. Anchor
|
|
module-owned validation and build paths, including file-size exclusions, and
|
|
configured product-command execution at the selected module. Keep diagnostic
|
|
file paths repository-relative and expose both directories to product commands.
|
|
Markdown destinations remain relative to their source documents.
|
|
Normalize selections and resolve path bases at a shared boundary. Translate
|
|
file selections and exclusions to canonical repository-relative paths before
|
|
checks consume them. Use module-based filesystem paths for execution and output,
|
|
and retain repository-relative diagnostic paths through conversions.
|
|
|
|
Root profiles use the repository-root module by default. Nested-module launchers
|
|
use the provided repository context for shared scripts. These conventions keep
|
|
per-module profiles self-contained without adding per-check path-base switches.
|
|
|
|
### Complete operation support
|
|
|
|
Implement module selection across checking, publication, artifact builds,
|
|
hosted delivery, and CI in this feature. The target is a coherent release API
|
|
for root and nested modules. CommandKit's current source-only use supplies an
|
|
adoption case while the feature supports the full existing release workflow.
|
|
|
|
Feature completion includes all of these operations. Omitted module selection
|
|
uses the root module, and source publication and asynchronous delivery retain
|
|
their separate outcomes.
|
|
|
|
### Clean API and receipt cutover
|
|
|
|
Implement one current API and module-bound receipt format as the complete
|
|
supported interface after cutover. Consumers update their calls, profiles, and
|
|
CI declarations to that interface and regenerate prior receipts through the
|
|
updated build operation. Compatibility shims and legacy receipt readers are
|
|
outside the implementation scope.
|
|
|
|
Migration means guidance supplied in the next release's documentation. That
|
|
guidance explains the required consumer changes and the root-module validation
|
|
scope change; implementation completion covers the new interface directly.
|