166 lines
9.2 KiB
Markdown
166 lines
9.2 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
|
|
`ssh://git@forge.maximumdirect.net:22222/base-layer/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.8.0 (`go.maximumdirect.net/releasekit`) owns candidate validation,
|
|
publication guards, tag creation, tag publication, and outcome reporting.
|
|
Its pinned public contracts are the
|
|
[CLI reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/cli.md),
|
|
[profile reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/config.md),
|
|
and [publication guide](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/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://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/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.
|
|
ReleaseKit also attempts to save private publication evidence under the
|
|
repository's Git common directory, shared by linked worktrees. It reports the
|
|
saved record path or a recording warning separately from publication status;
|
|
a storage failure does not change publication status. Records can contain
|
|
credential-bearing endpoints. Retain them privately while recovery is needed
|
|
and remove them when their recovery value expires; retention is maintainer-owned.
|
|
|
|
On an ambiguous result, use the recovery command printed for that invocation's
|
|
saved record. To discover records and explicitly select the matching attempt,
|
|
the bootstrapped executable can also be used from the repository root:
|
|
|
|
```sh
|
|
./.releasekit/bin/releasekit publication-attempts --repo .
|
|
./.releasekit/bin/releasekit reconcile --record /absolute/path/to/attempt.json
|
|
```
|
|
|
|
Replace the example record path with the saved path for the intended attempt.
|
|
Discovery lists local evidence without querying remotes or selecting an attempt.
|
|
Reconciliation observes the recorded endpoint, full tag, and tag object without
|
|
rerunning candidate validation or changing tags. It distinguishes confirmed
|
|
publication, current absence, conflict, and an unresolved observation. Current
|
|
absence does not prove that a version was never published. The pinned
|
|
[CLI reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/cli.md#recover-a-saved-publication-attempt-or-discover-local-attempts)
|
|
owns recovery statuses and structured output; the
|
|
[publication guide](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/consumers/publish.md#retain-and-reconcile-publication-evidence)
|
|
describes record storage and recovery entry points.
|
|
|
|
If no usable record was saved, use the exact endpoint, full tag, and annotated
|
|
tag object reported by that invocation. Query only that exact tag ref at the
|
|
captured endpoint. An exact tag-object match confirms publication, a different
|
|
object is a conflict, successful output without the ref shows current absence,
|
|
and a failed query leaves the result unresolved. Do not infer the captured
|
|
endpoint's state from another remote or a rewritten URL. Resolve unknown
|
|
publication state before retrying.
|
|
|
|
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.
|