Files
commandkit/docs/release.md

138 lines
7.4 KiB
Markdown

# CommandKit release procedure
## Scope and release order
CommandKit publishes source-only Go module releases. Each module has an
independent version and immutable annotated tag. This procedure publishes no
hosted release page, binaries, checksums, or other delivery assets. A successful
source-tag push is release completion; CI, module proxy availability, and
consumer installation are not completion gates.
Publish in dependency order: core, then `ckconfig`, then `ckprompt`. The
integration modules require the preceding CommandKit releases, so prepare and
publish each module only after its CommandKit dependencies are available. A root
release runs only the root module's default suite; it need not run suites for
independently released integrations.
Use branch `main`, remote `origin`, and expected effective push endpoint
`https://gitea.maximumdirect.net/eric/CommandKit.git`. The selected module profile
enforces the endpoint. The maintainer needs the selected
[release toolchain](#release-toolchain), Git push access, and a POSIX shell.
This procedure follows the [release policy](policy/release.md); release-note
footers follow the [OSS discoverability policy](policy/oss.md#discoverability).
ReleaseKit v0.4.2 owns candidate validation, publication guards, tag creation,
tag publication, and outcome reporting. Its pinned public contracts are the
[CLI reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/7d033c5ca1c95aec7db9690293638a0a1ac887b8/docs/cli.md),
[profile reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/7d033c5ca1c95aec7db9690293638a0a1ac887b8/docs/config.md),
and [publication guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/7d033c5ca1c95aec7db9690293638a0a1ac887b8/docs/consumers/publish.md).
The repository selects one default module suite per invocation. The launcher
bootstraps the native tool into ignored `.releasekit/` storage and delegates to
its `publish` command.
## Release toolchain
The selected release toolchain is **Go 1.26.8**. Each module declares a consumer
minimum of **Go 1.26.0**. Maintainers use Go 1.26.8 for dependency preparation,
candidate validation, and the ReleaseKit bootstrap. The
[consumer guide](consumers/guide.md#go-compatibility) and
[release policy](policy/release.md#consumer-minimum-and-release-toolchain)
describe these selections.
Select Go 1.26.8 on `PATH`; the launcher uses `GOTOOLCHAIN=local`. If needed,
install it with the standard Go tools:
```sh
GOWORK=off GOTOOLCHAIN=local go install golang.org/dl/go1.26.8@latest
go1.26.8 download
export PATH="$(go1.26.8 env GOROOT)/bin:$PATH"
hash -r
GOWORK=off GOTOOLCHAIN=local go version
```
## Modules, versions, notes, and shared files
Select exactly one module with the launcher:
| Selector | Physical module directory | Release note | Full tag |
| --- | --- | --- | --- |
| `core` | repository root | `docs/releases/<version>.md` | `<version>` |
| `ckconfig` | `integrations/ckconfig` | `integrations/ckconfig/docs/releases/<version>.md` | `integrations/ckconfig/<version>` |
| `ckprompt` | `integrations/ckprompt` | `integrations/ckprompt/docs/releases/<version>.md` | `integrations/ckprompt/<version>` |
Use a fresh stable semantic version (`vMAJOR.MINOR.PATCH`) for the selected
module. Before `v1.0.0`, a minor release may change a documented contract when
its note explains the impact and consumer action. Never reuse a published
version. Each release note starts with a product title and exact version, gives
a proportionate summary and compatibility guidance, and ends with immutable
links to that module's local grant, license, and attribution paths. The full tag
in each URL includes the integration directory where applicable. Future tag
URLs need not resolve before publication.
All three release profiles explicitly select the repository-root `COPYRIGHT`,
`LICENSE`, and `docs/oss/attribution.md` through `validation.shared_files`.
ReleaseKit requires these committed files to exist in the candidate even when
no optional file checks are enabled. The list does not enable content checks
or expand Go validation scope; see the pinned [profile reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/b96262eb0ce9c8f2eb3e948a5841db2b799bc91b/docs/config.md).
Each integration also distributes its own `COPYRIGHT`, `LICENSE`, and
`docs/oss/attribution.md`. These module-local materials are separate from the
explicit root shared-file list and remain subject to the [OSS policy](policy/oss.md).
Automatic module file inputs include applicable module-local files and stop at
independent nested-module boundaries. Their inclusion does not itself enable
license or content validation.
The current profiles enable no optional file checks or additional product
checks. Publication runs the selected module's standard offline suite and
ReleaseKit's candidate/note and publication guards. The profiles select their
physical module directory while using the same repository and endpoint.
## Prepare and publish one candidate
Prepare dependencies in the selected module before the candidate is finalized.
Do this after the preceding CommandKit module has been published and before the
selected candidate suite is run. For `core`, run the command at the repository
root; for integrations, run it from that module directory. Commit any resulting
`go.mod` or `go.sum` changes with the release candidate. The sum files must
reflect dependencies actually downloaded for that module; do not fabricate
future sums.
Then commit the selected module's release note and all intended candidate
changes on `main`, and publish the candidate commit to `origin`. Set one
selector, module directory, and version from the table above, then run:
```sh
module_dir=.
module_selector=core
module_version=v0.2.0
(cd "$module_dir" && GOWORK=off GOTOOLCHAIN=local go mod download)
# Commit reviewed dependency changes and the selected module's note on main.
git push origin HEAD:refs/heads/main
./scripts/release "$module_selector" "$module_version"
```
Run only the command for the selected module. Its profile runs the complete
offline deterministic default suite once for that module, checks candidate and
remote guards, creates the annotated tag from the matching note, and pushes
only that full tag. `check` is available for diagnosis and is not a required
pre-publication command. The launcher does not push `main`; publish the
candidate commit first. Successful source publication does not wait for CI,
proxy availability, or downstream installation.
## Completion and ambiguous publication
A successful push to the expected endpoint completes the source release. On an
ambiguous result, use the exact endpoint, full tag, and annotated tag object
reported by that invocation. Confirm endpoint resolution has not changed, then
query only that exact tag ref. Compare the remote annotated tag-object ID with
the reported object: an exact match confirms publication, a different object is
a conflict, successful output without the ref proves absence at that endpoint,
and a failed query leaves the result unresolved. Do not infer the captured
endpoint's state from another remote or a rewritten URL.
ReleaseKit may retain a local tag after a failed push. Remove an unpublished
local tag only after proving absence at the captured endpoint and confirming
that the tag was never published or used by another release channel. Never
move, overwrite, recreate, or delete a published tag. Resolve conflicts with a
fresh version; corrections to published source require a new version.