Plan implementation of individual module releases

This commit is contained in:
2026-10-10 01:34:33 +00:00
parent f33023f8e0
commit dbfae9ea81
3 changed files with 861 additions and 200 deletions

View File

@@ -10,9 +10,9 @@ ReleaseKit's API and CLI. CommandKit's core and optional integrations provide th
consumer case. Each invocation should require only module selection, product
settings, and a semantic version, with ReleaseKit owning the common mechanics.
This roadmap describes the target and the work from the current baseline. It
does not select a ReleaseKit release version or prescribe a staged implementation
plan. The decisions recorded below govern the planned scope.
This roadmap defines the target state and its scope and ownership decisions.
The [implementation plan](implementation.md) owns the ordered work from the
current baseline. This roadmap does not select a ReleaseKit release version.
## Current baseline
@@ -69,212 +69,68 @@ 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.
## Work needed
## Capability requirements
### 1. Establish a shared module and release identity
### Module and release identity
**Rationale:** One resolved identity prevents checks and publication from using
different interpretations of the selected module or tag.
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.
**Target:** Distinct repository directory, module directory, semantic version,
and complete tag are available throughout candidate handling and public evidence.
### Coherent validation scope
**Work:** Add an optional repository-relative module selection to the public
request and profile, with root defaults. Resolve it against the captured
repository and source appropriate to the operation once at the operation entry
point. Check, publication, and delivery use committed module declarations.
Standalone builds use the selected module's working-tree `go.mod`, following
the [declaration-source decision](#declaration-source-by-operation).
Pass the resolved identity through the operation's validation, publication,
build, and delivery collaborators. Standalone operations use the same resolution
logic. Derive tags using Go's standard module conventions, including
major-version directories: a `/v2` module stored at `integrations/ckconfig/v2`
uses `integrations/ckconfig/v2.0.0` for `v2.0.0`.
The same module stored at `integrations/ckconfig` uses that complete tag too.
Support both physical layouts and distinguish the module directory from its
tag prefix.
Carry the resolved identity through facade conversions, internal requests,
callbacks, results, and CLI diagnostics. Keep semantic-version validation
separate from full-tag handling. Exact field names belong in API design.
Keep shared identity resolution separate from each operation's prerequisites.
Populate resolved identity in public evidence as resolution succeeds, including
when a later step fails.
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.
### 2. Apply one validation scope
### Notes, publication, and recovery
**Rationale:** Consumers should select the release unit once and receive
consistent validation across enabled checks.
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.
**Target:** Tests, vet, package compilation, formatting, distribution checks,
file-size checks, Markdown, and product-check context all correspond to the
selected module and its relevant release materials.
### Builds, receipts, and hosted delivery
**Work:** Give the existing shared validation path both repository context and
module scope. Run Go commands in the module directory with the existing
offline and workspace-disabled environment. Select committed file inputs once
under the agreed boundary convention and apply that selection to each content
check. Build one ordered input set and retain the full repository lookup
separately for resolving Markdown destinations and existing committed-file
references. A link to another module may be checked for existence or its
target heading without scanning that module's unrelated documents.
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.
Update module-distribution inspection to examine the selected release's inputs.
For example, an unrelated sibling's filesystem replacement should not fail the
selected module's check. Add shared files through the
[resolved selection rules](#shared-file-validation-inputs), carrying the selection
through the public request and profile and applying it to the shared file inputs.
Keep the optional checks optional and retain their existing individual rules,
error identities, cancellation, and cause propagation apart from the intended
scope change. Apply the boundary and path conventions recorded below.
### CLI and module-selected CI
### 3. Bind notes and publication to the resolved identity
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.
**Rationale:** Different modules can use the same semantic version while
publishing distinct source identities and release notes.
### Complete adoption guidance and behavioral evidence
**Target:** The selected module's committed note identifies its product and
semantic version. Publication and recovery address its complete tag.
**Work:** Resolve module-local note paths and retain existing title validation
and captured note bytes. Thread the complete tag through local guards, remote
guards, annotated-tag creation, exact-object push, and bounded reconciliation.
Include the module, version, and resolved tag in success and failure evidence
as available, alongside commit, endpoint, phase, state, and tag object. Preserve
the existing publication outcomes and repository checks. Root notes and tags
retain their ordinary forms.
### 4. Carry module identity through builds and delivery
**Rationale:** A selected module should mean the same release unit throughout
ReleaseKit's supported operations.
**Target:** Standalone builds, candidate build checks, direct delivery, and
prebuilt-asset delivery all operate on the selected module. Hosted pages use
its complete tag and module-local note; binaries report its semantic version.
**Work:** Extend build and delivery requests and profile mapping with the
shared module identity. Resolve main packages and module-owned build paths
from the module directory. Prepare build dependencies there, and preserve
existing offline artifact compilation and version smoke checks. Reuse
operation-local Go settings between validation and subsequent builds when
their environment inputs match. Carry module identity through build results
and receipts so prebuilt delivery verifies the selected module, version, tag
where applicable, candidate commit, settings, and artifact hashes. Keep
ordinary local builds usable without requiring a published tag.
Use the full tag for tagged-checkout verification, Gitea release lookup and
creation, and source links. Use the semantic version for binary version injection
and module release titles. Select the module-local note and retain existing
page/asset conflict, retry, and partial-delivery behavior. Test source URLs with
slash-containing tags. Distinct module tags can have separate Gitea pages at the
same commit. A page-only profile continues to require no application binary.
Use the new module-bound receipt format for prebuilt delivery. Consumers
regenerate receipts through the updated build operation as part of the clean
cutover described below.
Normalize build settings once for build execution, receipt binding, and
comparison. Receipt loading owns structure and identity validation; delivery
owns the local content-verification pass before hosted requests. Build-time
hashing records produced bytes independently.
### 5. Support module-aware CI delivery
**Rationale:** Local operations and tagged-source delivery need the same module,
profile, and version selection.
**Target:** The maintained consumer workflow accepts root and nested-module tags,
selects the corresponding profile, and delivers only that module's release.
Tool selection follows the tagged module configuration under
[ADR 0004](../adr/0004-module-selected-tooling.md).
**Work:** Extend tagged-checkout preparation and `ci-deliver` to distinguish the
full event tag from the semantic version. Adapt tag filters, profile selection,
tool bootstrap, and application dependency preparation. Use an explicit
module/profile mapping or equivalent small consumer declaration from the
verified tagged checkout. Resolve the physical module directory and profile
before tool bootstrap, and keep the selection consistent with the derived tag.
Verify the event commit before resolving that mapping and use the tagged
source's selected module files on retries.
Use the same small consumer selection declaration for the launcher and CI.
Bootstrap selects the module and profile; ReleaseKit verifies their consistency
with the derived identity. Reuse the verified checkout after tool bootstrap
with fresh read-only source checks. Standalone `ci-deliver` owns preparation
when it is needed.
For ordinary root tags, use the root profile and module bootstrap defaults.
Consumers using that pattern supply no module/profile mapping declaration.
Preserve temporary bootstrap metadata and existing credential handling. Cover
major-version directory layouts without assuming that trimming the tag always
identifies the physical module directory. Include page-only and binary examples.
### 6. Make API and CLI adoption small and coherent
**Rationale:** The shared release operation should replace consumer publication
logic with small per-module declarations.
**Target:** A shared launcher can select a profile and pass a semantic version;
API consumers express the equivalent operation. Additional checks receive
module context and repository context for explicit composition work.
**Work:** Map profile selection into the shared request, document relative-path
behavior, and provide module/tag context to configured commands. Retain existing
profile selection through `--config`; a separate CLI override for the module is
not needed to satisfy the initial request. Add a maintained multi-module example
showing root and integration profiles and a small shared launcher. Show dependency
preparation before offline validation and sequential sibling releases when a
dependency version must be published first. Keep product checks focused on
consumer assertions instead of repeating the standard suite.
Preserve the [simple root-module experience](#simple-single-module-experience),
including a small
profile, launcher, and CI workflow with no additional required declarations.
### 7. Verify and document the complete behavior
**Rationale:** This changes release identity and validation boundaries, including
the behavior of root modules with nested modules.
**Target:** Representative public API and CLI workflows establish that the
selected module is validated and only its intended tag is published.
**Work:** Extend existing behavioral tests using local repositories and
remotes. Cover root defaults; nested-module failure while the root suite
passes; equal versions across modules; major versions with and without
physical major-version directories; full-tag reuse; and failed or unknown
publication with the correct recovery identity. Exercise optional checks with
violations inside and outside the selected scope, parent selection excluding
independent nested modules, and cross-module Markdown references. Cover
omitted, replacement, and empty shared-file lists; optional default files;
missing explicit files; committed-tree lookup; duplicate inputs; and explicit
files in another module. Verify selection errors when optional file checks are
disabled, and that shared-file selection preserves enabled checks and Go
scope. Verify that repository guards still observe changes outside the
selected module and that module selection does not repeat the standard suite.
Reuse existing failure tests where they already protect unchanged behavior.
Add representative nested-module build/version-injection, new-format receipt
ownership and cutover, Gitea page/asset, and CI tag/profile/tool-selection
coverage. Use local HTTP servers for delivery and isolated synthetic module
proxies for bootstrap tests. Verify that retries use the original module
selection and full tag after the default branch changes. Verify a
representative simple root-module API call, profile, launcher, and CI workflow
using the new interface's defaults. Confirm that routine use adds no required
configuration fields, mapping declarations, or consumer decisions. Give
identity derivation, scope selection, and path conversion focused tests at
their owners. Use representative assembled workflows and reuse existing
failure coverage where the underlying behavior remains shared. Verify
preserved empty lists, contextual findings for equal blobs at different paths,
failure identity, and artifact-verification ownership. Cover standalone builds
with modified declarations or new module directories, composite builds using
committed identity, and source verification required for delivery.
Update GoDoc, CLI/configuration references, check/publication/build/delivery guides,
adoption examples, CI templates, and recovery guidance together. Supply migration
guidance in the next release's documentation, covering API and profile updates,
receipt regeneration, CI mapping, and root-module scope changes, including
exclusion of nested fixture modules from automatic file checks. Document
semantic version versus full tag in note titles and source/licensing links.
ReleaseKit's own maintainer policy continues to describe its root-module release;
consumer guidance explains how
multi-module consumers adapt their policies. Run the normal offline suite and
public API checks for implementation changes; validate documentation links and
examples. Synthetic dependency fixtures use isolated module caches.
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
@@ -459,9 +315,9 @@ 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.
Implementation may proceed in stages; feature completion includes all of these
operations. Omitted module selection uses the root module, and source publication
and asynchronous delivery retain their separate outcomes.
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