Document the source release workflow

This commit is contained in:
2026-10-08 16:49:01 +00:00
parent d3f0891225
commit 8c5fea0aae
12 changed files with 197 additions and 34 deletions

View File

@@ -21,13 +21,16 @@ The [consumer guide](docs/consumers/guide.md) links to two maintained examples:
- [Command line reference](docs/cli.md)
- [Consumer guide](docs/consumers/guide.md)
- [Internal package overview](docs/internal/overview.md)
- [Maintainer release procedure](docs/release.md)
- [Architecture policy](docs/policy/architecture.md)
- [Policy provenance](docs/policy/meta.md)
## Planning history and future work
- [Initial delivery and deferred capabilities](docs/roadmap/initial.md)
- [Completed implementation record](docs/roadmap/implementation.md)
- [Completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
- [ReleaseKit adoption roadmap](docs/roadmap/releasekit.md)
- [Release tooling implementation plan](docs/roadmap/implementation.md)
- [Historical CLI planning](docs/roadmap/01-cli-plan.md)
- [Completed dispatcher planning](docs/roadmap/02-dispatch.md)
- [Completed backend planning](docs/roadmap/03-backend.md)

View File

@@ -53,16 +53,19 @@ canonical documentation owners.
| Backend integration | [Internal overview](internal/overview.md), [adapter implementation](../internal/cobra/parse.go), and [ADR 0002](adr/0002-cobra-backend.md) |
| Public facade or adapter boundaries | [Internal overview](internal/overview.md), [ADR 0003](adr/0003-public-facade.md), and the architecture policy |
| Deferred capabilities and delivery scope | [Initial feature target](roadmap/initial.md#deferred-capability-targets) and [explicit deferrals](roadmap/initial.md#explicit-deferrals) |
| Initial planning history | [CLI](roadmap/01-cli-plan.md), [dispatcher](roadmap/02-dispatch.md), [backend](roadmap/03-backend.md), [facade](roadmap/04-facade.md), and [completed staged plan](roadmap/implementation.md) |
| Initial planning history | [CLI](roadmap/01-cli-plan.md), [dispatcher](roadmap/02-dispatch.md), [backend](roadmap/03-backend.md), [facade](roadmap/04-facade.md), and [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) |
| Release tooling | [Maintainer release procedure](release.md), [ReleaseKit adoption roadmap](roadmap/releasekit.md), and [release tooling implementation plan](roadmap/implementation.md) |
| Licensing or incorporated material | [Project grant](../COPYRIGHT), [license texts](../LICENSE), and [attribution](oss/attribution.md) |
| Policy provenance | [Policy provenance](policy/meta.md) |
Read all applicable rows for cross-cutting work. Go declarations and GoDoc own
current exported contracts; the CLI reference owns operator behavior. Numbered
roadmaps are completed planning records. Retained illustrations and historical
staged instructions are not current API references or assignments to restart
implementation. Future capabilities remain explicitly identified in the feature
roadmap.
current exported contracts; the CLI reference owns operator behavior. The
initial numbered roadmaps are completed planning records. The
[ReleaseKit adoption roadmap](roadmap/releasekit.md) and its
[implementation plan](roadmap/implementation.md) track current maintainer
tooling work. Retained illustrations and historical staged instructions are not
current API references or assignments to restart implementation. Future
capabilities remain explicitly identified in their feature roadmaps.
## Documentation validation
@@ -86,9 +89,20 @@ references, not build dependencies. Implemented contracts belong in CommandKit
under their canonical owners.
Run `go test ./...` from the repository root to compile the module and run its
deterministic tests. Format changed Go files with `gofmt`. The release procedure
and publication tooling will be introduced with a releasable module under the
release policy.
deterministic tests. Format changed Go files with `gofmt`. The
[maintainer release procedure](release.md) owns candidate preparation and
publication commands.
## Release tooling development
The local publication exercise is opt-in and uses disposable Git repositories.
Prepare the module cache before running it; ordinary tests do not bootstrap or
publish a release:
```sh
GOWORK=off GOTOOLCHAIN=local go mod download
COMMANDKIT_RELEASE_INTEGRATION=1 GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off go test -mod=readonly -count=1 ./scripts -run '^TestReleaseIntegration$'
```
Follow the [local commit policy](policy/agents.md#git-commit-policy). Completed
units receive local commits by default, subject to explicit user instructions.

View File

@@ -2,7 +2,7 @@
**Base Policy Version:** 1.4
**Last Updated**: 2026-10-06
**Last Updated**: 2026-10-08
**Upstream Source:** [release.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md)
@@ -20,13 +20,10 @@ policy and link to it rather than introduce additional release requirements.
CommandKit releases source-only Go modules. Standard CLI behavior is exposed by
consuming applications; CommandKit does not declare binary deliverables or a
cross-platform build matrix. The publication procedure and its tooling will be
introduced with a releasable module. Do not create a placeholder publisher or
claim that a release command exists before implementation.
ReleaseKit may provide future publication mechanics, but its integration has not
been selected. Adopt concrete checks for CommandKit's risks; do not copy another
repository's platform commitments or validation gates.
cross-platform build matrix. ReleaseKit v0.2.0 is selected as the maintainer
publication tool. The [release procedure](../release.md) owns its source-only
workflow and repository-specific commands; the integration adds no application
command family or runtime ReleaseKit import.
## Release Model And Completion

133
docs/release.md Normal file
View File

@@ -0,0 +1,133 @@
# CommandKit release procedure
## Scope and prerequisites
CommandKit publishes source-only Go module releases: an immutable annotated
version tag for one committed candidate and its matching checked-in release
note. This procedure does not publish a hosted release page, binaries,
checksums, or other delivery assets, and it requires no delivery credentials.
Use branch `main`, remote `origin`, and the expected effective push endpoint
`https://gitea.maximumdirect.net/eric/CommandKit.git`. The profile enforces that
endpoint during publication. The maintainer needs a local Go toolchain
compatible with the module's Go 1.25.5 minimum, Git with push access to `origin`,
and a POSIX shell.
This procedure follows the [release policy](policy/release.md); the release-note
footer follows the [OSS discoverability policy](policy/oss.md#discoverability).
ReleaseKit v0.2.0 owns candidate validation, publication guards, annotated tag
creation, tag publication, and outcome reporting. The repository profile selects
only its default candidate suite. The launcher bootstraps the module-selected
native executable into ignored `.releasekit/` storage and invokes its `publish`
command. The upstream [CLI reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/cli.md),
[profile reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/config.md),
and [publication guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/consumers/publish.md)
own detailed command, profile, and status contracts.
## Prepare and publish a candidate
Choose a fresh, unused stable Semantic Version tag in the form
`vMAJOR.MINOR.PATCH`, with no leading zeroes. Before `v1.0.0`, a minor release
may change a documented contract if its note explains the impact and consumer
action; a patch release must not intentionally break contracts within its
minor line. Never reuse a version previously published through any release
channel. The first version is selected during release preparation, not embedded
in the tool or profile.
Start from `main` and prepare a note at `docs/releases/<version>.md`. Begin with
a heading containing `CommandKit` and the exact version. Include a useful
summary and any compatibility impact or upgrade instructions. End it with the
license and attribution links at that version's immutable source tag, replacing
`VERSION` with the selected tag:
```markdown
[COPYRIGHT](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/COPYRIGHT) |
[LICENSE](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/LICENSE) |
[ATTRIBUTION](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/docs/oss/attribution.md)
```
Review these paths in the candidate; the future tag URLs do not need to resolve
before publication.
Prepare dependencies separately from the offline candidate suite:
Run these commands in the same shell session so the version variable remains
set:
```sh
commandkit_version=vX.Y.Z
GOWORK=off GOTOOLCHAIN=local go mod download
```
If dependency preparation changes `go.mod` or `go.sum`, review and commit those
changes with the candidate. Commit the note and all candidate changes on `main`,
then publish that commit to `origin`:
```sh
git push origin HEAD:refs/heads/main
./scripts/release "$commandkit_version"
```
The launcher builds the ReleaseKit version selected by the module in readonly
mode. After preflight, `publish` runs the offline default Go suite once, checks
the candidate and remote guards, creates an annotated tag from the committed
note, and pushes only that tag object. The launcher does not push `main`; push
the candidate first. Do not require a separate `check` before `publish` or repeat
the same suite. Successful source publication does not wait for CI, module
availability, or consumer installation.
## Completion and statuses
Publication is complete when the intended annotated tag is successfully pushed
to the expected endpoint, or when an exact tag-object query confirms that push
after an error. Status 0 reports confirmed publication. Status 1 reports a
known failure or conflict; status 2 reports invalid input or profile; status 3
means the push outcome remains unresolved. See the upstream [CLI status
contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/cli.md).
For a failed or ambiguous push, use the exact endpoint, version, and annotated
tag object reported by the invocation. Confirm that Git still resolves the
captured endpoint to itself before querying only that tag ref:
```sh
releasekit_endpoint='COPY THE CAPTURED ENDPOINT EXACTLY'
releasekit_version='vX.Y.Z'
releasekit_tag_object='COPY THE REPORTED TAG OBJECT ID'
releasekit_ref="refs/tags/$releasekit_version"
releasekit_resolved_endpoint=$(git ls-remote --get-url -- "$releasekit_endpoint") || {
printf '%s\n' 'publication state is unresolved: endpoint resolution failed' >&2
exit 1
}
if [ "$releasekit_resolved_endpoint" != "$releasekit_endpoint" ]; then
printf '%s\n' 'publication state is unresolved: endpoint resolution changed' >&2
exit 1
fi
releasekit_remote_tag=$(git ls-remote --refs -- "$releasekit_endpoint" "$releasekit_ref") || {
printf '%s\n' 'publication state is unresolved: remote query failed' >&2
exit 1
}
printf '%s\n' "$releasekit_remote_tag"
```
`--refs` returns the annotated tag object's ID, not its peeled commit. Compare
that ID with `releasekit_tag_object`: an exact match confirms publication; a
different object is a conflict; successful output with no matching ref proves
absence at the captured endpoint. A failed query or changed URL resolution is
unresolved, never evidence of absence. Do not query a different fetch URL or
follow a rewritten endpoint to infer the captured destination's state.
ReleaseKit retains a local tag after a failed push, so the tag blocks an ordinary
retry. After proving the tag absent at the captured endpoint,
confirm that it was never published or used by another release channel before
deliberately removing the unpublished local tag:
```sh
git tag -d "$releasekit_version"
```
Do not move, overwrite, recreate, or delete a published tag. If the exact tag
object is present remotely, keep it. Resolve conflicts with a fresh version;
corrections to published source require a new version. A transport failure
alone does not require a new version.

View File

@@ -9,8 +9,8 @@ Original review: 2026-10-06. Reconciled: 2026-10-07.
This document preserves the initial command-suite review and identifies remaining
future work. Its completed implementation tasks and obsolete contract drafts
have been retired. The [initial feature target](initial.md) and
[completed implementation plan](implementation.md) record delivery scope and
execution history.
[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
record delivery scope and execution history.
The [CLI reference](../cli.md) owns implemented commands, syntax, formats, and
outcomes. Go declarations and GoDoc own exact exported APIs; the

View File

@@ -10,7 +10,8 @@ Original planning: 2026-10-06. Reconciled: 2026-10-07.
registry, and typed-input decisions and rationale. The
[architecture policy](../policy/architecture.md) owns responsibility boundaries.
This document records completion of the initial dispatcher design; the
[implementation plan](implementation.md) preserves its execution history.
[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
preserves its execution history.
The registry, typed inputs, command/group APIs, invocation coordination, and
outcomes are implemented. Their exact contracts are owned by Go declarations

View File

@@ -27,7 +27,8 @@ The [CLI reference](../cli.md) owns observable syntax and presentation.
The initial implementation translated registered metadata through a neutral
bridge, rebuilt backend state for each invocation, and adapted backend routing,
local flags, operands, presence, help, and syntax failures to selected semantics.
The [completed plan](implementation.md) records these stages and their checks.
The [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
records these stages and their checks.
The earlier discussion of rejecting repeated singletons was superseded by the
accepted last-occurrence rule in [ADR 0006](../adr/0006-command-grammar.md).

View File

@@ -16,7 +16,7 @@ the [consumer guide](../consumers/guide.md) explains their use. The
[internal overview](../internal/overview.md) owns the actual package inventory,
and [go.mod](../../go.mod) owns dependency versions.
The [initial target](initial.md) and [completed implementation plan](implementation.md)
The [initial target](initial.md) and [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
record the chosen layout and delivered API work. The initial implementation
requires no further facade package construction.

View File

@@ -369,7 +369,7 @@ the stage.
## Stage 5: document operation and reconcile release navigation
**Status:** pending. **Prerequisite:** Stage 4.
**Status:** complete. **Prerequisite:** Stage 4.
**Files:** new `docs/release.md`; `docs/policy/release.md`, README,
`docs/development.md`; historical roadmap references listed below; and stage
@@ -444,6 +444,18 @@ licensing footer navigation, intended release URL paths, changed historical
references, provenance, and Markdown whitespace. No publisher invocation on
CommandKit or another full test suite is needed for these prose edits.
Observed 2026-10-08: added `docs/release.md` with source-only preparation,
publication, status, and exact-object recovery instructions. The runbook was
reviewed against the profile, launcher, release policy, OSS policy, and ReleaseKit
v0.2.0 references. The policy retains its base version and upstream provenance
with an updated local date. README and developer navigation link to the runbook;
the developer guide records the optional local exercise. Historical references
now use the immutable initial-plan snapshot, while current ReleaseKit work links
to its roadmap and this plan. A link check found 228 valid local destinations and
fragments across 11 affected documents; Markdown whitespace checks passed. The
README's licensing and attribution footer remains intact. No real publication
or full test suite was run for this prose stage.
**Completion:** implemented tooling has one canonical runbook, policy status is
accurate, and old library history is distinguishable from current ReleaseKit
work. Commit the stage.

View File

@@ -5,9 +5,10 @@ Status: roadmap preparation and implementation-plan handoff complete.
Date: 2026-10-07.
The [feature roadmap](initial.md) records the selected initial target and its
completion. The [implementation plan](implementation.md) was prepared from that
review and has been executed. Checked entries below record the completed
preparation process; they are not assignments to restart planning.
completion. The [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md)
was prepared from that review and has been executed. Checked entries below
record the completed preparation process; they are not assignments to restart
planning.
## Historical preparation process

View File

@@ -9,7 +9,7 @@ Date: 2026-10-07.
This document defines the selected initial target for the library: packages,
features, integration contracts, dependencies, and completion evidence. It was
prepared using [the agreed checklist](initial-plan.md). Implementation steps and
stage evidence belong in [the completed implementation plan](implementation.md).
stage evidence belong in the [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md).
Detailed specifications below preserve the selected design baseline; they are
planning history, not a parallel current API or operator reference. The included
target is implemented; the table below records feature status.
@@ -592,11 +592,11 @@ framework, general dependency injection, concurrent-dispatch guarantees, and
implementation of additional library families. None is needed to prove the
initial selected feature target. Application-owned commands remain extensible.
Consumer migrations, release publication, and ReleaseKit integration are separate
work. Initial implementation should be a usable module with maintained examples;
source-release tooling is planned under the release policy when preparing a
releasable candidate. Do not create placeholder publisher commands or a binary
build matrix.
Consumer migrations and source publication were kept outside the initial
library target. Current ReleaseKit adoption is tracked in the
[adoption roadmap](releasekit.md) and its [implementation plan](implementation.md).
The initial implementation targeted a usable module with maintained examples;
it did not create placeholder publisher commands or a binary build matrix.
## Completion criteria

View File

@@ -138,7 +138,8 @@ labeled the retained process and outline as historical.
## D-06: clarify completed feature and implementation records
Owners: [initial.md](initial.md) and [implementation.md](implementation.md).
Owners: [initial.md](initial.md) and the
[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md).
- [x] Replace ownership statements written in future tense in the feature roadmap with
links to the existing GoDoc and CLI reference. Clearly identify detailed