208 lines
13 KiB
Markdown
208 lines
13 KiB
Markdown
# Implement ReleaseKit adoption
|
||
|
||
Status: Planned. Implement the stages below in order. The target state and
|
||
policy choices are in the [ReleaseKit adoption roadmap](releasekit.md); this
|
||
plan is the execution checklist. Use ReleaseKit v0.2.0 at tagged commit
|
||
`e030794969fb7787e647a90bbc4eb81bd0610f07` for the initial migration.
|
||
Do not publish a real ConfigKit version as part of implementation. Keep the
|
||
current release procedure authoritative until the replacement is working.
|
||
Follow the task-specific reading guide in [development.md](../development.md)
|
||
and avoid adding gates, compatibility promises, or restrictions beyond the
|
||
roadmap and adopted policies. Stages 3–5 are one documentation-and-machinery
|
||
cutover; do not commit or hand off their intermediate state as a release-ready
|
||
candidate.
|
||
|
||
## Stage 1: Select Go and declare the release tool — Complete
|
||
|
||
1. Identify the latest locally available patch in the newest stable Go series
|
||
available in the development environment. Make it the `go` on `PATH` and
|
||
verify it with `GOTOOLCHAIN=local go version`. Keep ConfigKit's current
|
||
`go.mod` `go` minimum until the release-workflow cutover in Stage 4: the
|
||
existing release checker still selects Go 1.25 and cannot validate a module
|
||
requiring Go 1.26. Do not substitute an automatically downloaded toolchain
|
||
during later validation.
|
||
2. Using that same Go executable, add
|
||
`gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@v0.2.0` as a
|
||
`go.mod` tool dependency (the Go `tool` directive and its module
|
||
requirement). Update `go.sum`, run `go mod tidy`, and inspect the module
|
||
diff. Preserve ConfigKit's runtime dependency boundary: production library
|
||
packages must not import ReleaseKit. Do not introduce a second tool-version
|
||
pin or an `@version` installation path in the release procedure.
|
||
3. Prepare the module cache and build the selected CLI package with that Go
|
||
executable into a temporary path outside the worktree. Confirm that the
|
||
resolved ReleaseKit module is v0.2.0 and that the built executable runs.
|
||
Review actual dependency and license treatment under the
|
||
[OSS policy](../policy/oss.md); a tool used only for development and release
|
||
work does not by itself require an attribution entry.
|
||
|
||
Completion evidence: `go.mod` retains its current Go minimum and selects the
|
||
pinned ReleaseKit tool, `go.sum` is consistent, `go mod tidy` leaves no
|
||
unintended changes, the module-selected executable builds with the selected
|
||
local Go, and the ordinary offline Go suite still passes after dependencies
|
||
are prepared. If the new tool dependency itself requires a higher minimum,
|
||
handle that compatibility change together with the cutover rather than
|
||
leaving the current release checker unusable.
|
||
|
||
## Stage 2: Add ConfigKit's ReleaseKit profile — Complete
|
||
|
||
1. Add `releasekit.json` at the repository root with `product` set to
|
||
`ConfigKit`, `remote` set to `origin`, and `expected_push_url` set to
|
||
`https://gitea.maximumdirect.net/eric/ConfigKit.git`. Select
|
||
`validation.go.race: true`, `validation.go.full_vet: true`, and
|
||
`validation.go.compile_targets` in this order: `linux/amd64`, `linux/arm64`.
|
||
Omit `build`, `delivery`, `checks`, and the other optional validation
|
||
selections. This is a source-only release; macOS is best effort.
|
||
2. Add one small, offline ConfigKit-owned test of the committed profile's
|
||
selected identity, endpoint, and checks. Keep it limited to configuration
|
||
wiring and the agreed gate set; do not replicate ReleaseKit's publication,
|
||
recovery, or Go-check implementation tests. Stage 6 will exercise the
|
||
profile with the actual tool against an isolated remote.
|
||
|
||
Completion evidence: the profile is valid JSON, the focused test and ordinary
|
||
Go suite pass, and review shows only the selected gates and no binary or hosted
|
||
delivery configuration.
|
||
|
||
## Stage 3: Align release policy with the adopted workflow — Complete
|
||
|
||
1. Revise [the release policy](../policy/release.md) so candidate preparation
|
||
explicitly publishes the committed candidate to authoritative `main`
|
||
before the one ReleaseKit `publish` invocation validates it and publishes
|
||
the annotated tag. Keep the checked-in note and tag as the only deliverables,
|
||
successful intended-tag publication as completion, and CI, macOS, hosted
|
||
delivery, and consumer retrieval outside release gates.
|
||
2. Replace references to the local release scripts and fixed Go 1.25 release
|
||
baseline with the selected local Go executable, the current `go.mod`
|
||
minimum, the module-selected ReleaseKit CLI, its one race suite with
|
||
test-time vet disabled, full vet, and Linux amd64/arm64 package compilation.
|
||
State that preparation records the initial stable release of the newest
|
||
locally available Go series in `go.mod`, retaining a higher patch minimum
|
||
only when required by a dependency or specific correctness fix. Use the
|
||
latest locally available compatible patch in that series for ReleaseKit's
|
||
build and validation, and review any minimum-version increase under
|
||
existing compatibility rules. Keep dependency acquisition and tool build
|
||
before offline candidate validation; do not add a separate successful test
|
||
or CI run as a publication prerequisite.
|
||
3. Align the guard descriptions with ReleaseKit v0.2.0: use its release-note
|
||
H1 and exact effective push-URL checks, rather than claiming an automated
|
||
exact-first-line or configured fetch-URL check. Retain the required
|
||
`# ConfigKit <version>` first-line format for notes, the source/tag
|
||
immutability rules, and the existing recovery principles. Do not require
|
||
per-test skip listings; test failures still block publication.
|
||
|
||
Completion evidence: policy and roadmap agree on order, gates, compatibility,
|
||
and completion; no policy passage still describes the retired script or its
|
||
stronger automated guards as current behavior.
|
||
|
||
## Stage 4: Replace the maintainer release runbook — Complete
|
||
|
||
1. Revise [the runbook](../release.md) into copyable steps for the adopted
|
||
process. During this cutover, move `go.mod` from its current minimum to the
|
||
first stable release of the newest Go series available in the development
|
||
environment (for example, `go 1.26.0` when using Go 1.26.8), unless a
|
||
dependency or specific correctness fix needs a higher patch minimum. Have
|
||
the runbook derive the series from `GOTOOLCHAIN=local go env GOVERSION` and
|
||
use `go mod edit` to record its `.0` release, without lowering an existing
|
||
required higher patch minimum. Keep that series' latest locally available
|
||
compatible patch first on `PATH` for both the tool build and validation.
|
||
Explain the minimum-Go compatibility impact and version choice, including
|
||
the pre-v1.0.0 minor-release rule. Prepare
|
||
dependencies, then build the module-selected `cmd/releasekit` with that
|
||
executable into temporary storage outside the repository. Use the native
|
||
executable for publication so its exit status and diagnostic state are
|
||
preserved. Its child Go commands must find the same selected `go` on `PATH`;
|
||
the old `CONFIGKIT_BASELINE_TOOLCHAIN` selector cannot choose them.
|
||
2. Keep ordinary candidate preparation: check access to the authoritative
|
||
remote, choose an unused stable version, review compatibility and content,
|
||
write `docs/releases/<version>.md` with the exact ConfigKit first line and
|
||
license footer, retire completed roadmaps, and commit the entire candidate.
|
||
Do not turn those reviews into additional approval gates. Push only that
|
||
committed candidate to authoritative `main` using the literal authoritative
|
||
URL and `HEAD:refs/heads/main` refspec, with implicit tag following
|
||
disabled. ReleaseKit requires the remote `main` to equal the candidate
|
||
before it validates. A failure before this push leaves publication
|
||
unstarted; a failed validation after it leaves an untagged `main` candidate
|
||
that must be corrected by a new commit and another validation.
|
||
3. Document one `releasekit publish vMAJOR.MINOR.PATCH` invocation using the
|
||
built, module-selected executable. Describe its selected race suite, full
|
||
vet, Linux package builds, release-note and effective-push-URL guards,
|
||
exact tag publication, and confirmed-tag completion. Keep `check` optional
|
||
for diagnosis, not a repeated required pass. Update the partial/unknown
|
||
push recovery directions to ReleaseKit's reported candidate, endpoint,
|
||
tag-object ID, and bounded authoritative-state reconciliation. Preserve
|
||
optional post-publication consumer verification and no-CI-wait behavior.
|
||
Remove old script commands, Go 1.25 pin examples, and promises of verbose
|
||
skipped-test output.
|
||
|
||
Completion evidence: a maintainer can follow the runbook from a clean checkout
|
||
through confirmed tag publication without a ConfigKit release wrapper or a
|
||
second required Go/test run; all commands, version placeholders, and documented
|
||
failure states match ReleaseKit v0.2.0. Do not execute its real publication
|
||
command in this stage.
|
||
|
||
## Stage 5: Retire duplicated machinery and update developer guidance — Complete
|
||
|
||
1. Remove `scripts/release.sh`, `scripts/release-check.sh`, and
|
||
`release_publish_test.go` after Stages 1–4 supply the replacement. Remove
|
||
`TestCheckScriptsReleaseGates` and its now-unused helpers from
|
||
`release_check_test.go`. Preserve
|
||
`TestDevelopmentCheckHandlesFilenamesAndStopsOnFailure` and
|
||
`scripts/check.sh`; rename the test file if helpful so its name reflects
|
||
its remaining owner. Retain the small Stage 2 profile-wiring test. Do not
|
||
transplant the old publication guard/recovery matrix into ConfigKit tests.
|
||
2. Update [the development guide](../development.md) to point to the new
|
||
release runbook, remove retired-script references and the fixed release
|
||
baseline, and adjust its task-to-test map. Keep the everyday development
|
||
check and release validation distinct. Review other live references to the
|
||
removed scripts and update only those made stale by this migration;
|
||
historical release notes remain unchanged.
|
||
|
||
Completion evidence: no live release instruction invokes a removed script;
|
||
the default suite and `./scripts/check.sh` pass with the selected Go and
|
||
prepared dependencies; the retained tests protect development checks and
|
||
profile wiring without duplicating ReleaseKit's generic behavior.
|
||
|
||
## Stage 6: Exercise the migration without publishing ConfigKit
|
||
|
||
1. Build ReleaseKit from the candidate's `go.mod` selection with the latest
|
||
selected local Go patch for that minimum's series. Use that same executable
|
||
for ReleaseKit's validation, without requiring its patch number to equal
|
||
the `go.mod` minimum. In disposable Git fixtures, use
|
||
ConfigKit's selected profile with only `expected_push_url` changed to a
|
||
temporary bare remote, and provide a matching committed fixture release
|
||
note. Never push a ConfigKit tag or source commit to its real remote.
|
||
2. Push a committed fixture candidate to temporary `main` and run the built
|
||
`publish` command with a deliberately failing fixture test. Confirm
|
||
validation fails and creates no release tag, while `main` remains at that
|
||
candidate. Correct and commit the fixture, push the new candidate to
|
||
temporary `main`, and run `publish` again. Confirm one race-enabled standard
|
||
suite, one full vet pass, and one CGO-disabled package compile for each
|
||
selected Linux target in that successful invocation; confirm the remote
|
||
annotated tag identifies the corrected candidate and contains the checked-in
|
||
note. Record child Go invocations with a fixture-only forwarding executable
|
||
on `PATH`, or use equivalent direct evidence, rather than inferring the
|
||
selected command count merely from success.
|
||
|
||
Completion evidence: the isolated failure and success paths demonstrate the
|
||
selected profile, module-selected tool, command order, gates, and tag-only
|
||
publication. No ConfigKit ref is pushed to its real remote.
|
||
|
||
## Stage 7: Check endpoint failure and finish the cutover review
|
||
|
||
1. In a fresh disposable fixture/version without an existing tag, check that
|
||
a wrong effective push URL is rejected before validation or tag
|
||
publication. Do not reuse the version already published in Stage 6, which
|
||
would make the existing-tag guard obscure the endpoint result.
|
||
2. Compare the runbook's recovery directions with ReleaseKit's reported state
|
||
for a failed or uncertain tag push. Repair any mismatch in the runbook;
|
||
do not duplicate ReleaseKit's recovery machinery in ConfigKit. This is a
|
||
bounded migration exercise, not a new per-release gate or a requirement to
|
||
wait for CI.
|
||
3. Re-run the affected repository checks after any corrections. Review the
|
||
final policy, runbook, development guide, and roadmap together for a
|
||
coherent process; confirm that only intended files changed and that no
|
||
real ConfigKit release or push occurred.
|
||
|
||
Completion evidence: the wrong-endpoint fixture fails for the intended reason,
|
||
recovery guidance matches ReleaseKit v0.2.0, tests and documentation checks
|
||
pass, and the repository is ready for a separately authorized release.
|