From c0605fab44d58bffc27c28a176e0949bb80b9e8c Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Thu, 8 Oct 2026 13:12:18 +0000 Subject: [PATCH] Plan ReleaseKit adoption --- docs/roadmap/releasekit.md | 134 +++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 docs/roadmap/releasekit.md diff --git a/docs/roadmap/releasekit.md b/docs/roadmap/releasekit.md new file mode 100644 index 0000000..7fa4838 --- /dev/null +++ b/docs/roadmap/releasekit.md @@ -0,0 +1,134 @@ +# Adopt ReleaseKit for source releases + +Status: Proposed. This roadmap uses ReleaseKit v0.2.0 (tagged commit +`e030794969fb7787e647a90bbc4eb81bd0610f07`) as the initial adoption +baseline. The [ReleaseKit release note](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/releases/v0.2.0.md) +summarizes its available capabilities. A later implementation plan will own +task order and acceptance checks. + +## Purpose and current baseline + +ConfigKit wants to use a common release process and retire duplicated local +release machinery. Today, [the release procedure](../release.md) uses +`scripts/release.sh` and `scripts/release-check.sh` to validate a committed +candidate, push it to `main`, and publish an annotated tag. Dedicated tests +exercise those scripts. The selected gates are one offline race-enabled Go +suite on a maintained Go 1.25 patch, one full vet pass, and CGO-disabled package +builds for Linux amd64 and arm64. The checked-in note and immutable tag are the +only declared deliverables. CI and macOS checks do not gate publication; no +hosted release page is declared. + +ReleaseKit v0.2.0 offers [profile selections](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/config.md) +for that same test, vet, and source-only compilation set. It runs the test +suite once, disables test-time vet when a separate full vet pass is selected, +and can require an exact effective push URL. Its +[publication contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/consumers/publish.md) +requires the candidate to be on authoritative `main` before validation and +pushes only the annotated tag. + +## Target end state + +ConfigKit remains a source-only Go library. Maintainers prepare the version, +compatibility assessment, and checked-in note as before, then publish the +committed candidate to authoritative `main`. One ReleaseKit `publish` +invocation validates that exact candidate and publishes its annotated tag. +Confirmed publication of the intended tag completes the release. A failed or +uncertain push follows ReleaseKit's bounded, exact-object recovery procedure. +If validation fails after the candidate is pushed to `main`, no release tag is +published; the corrected candidate requires another commit and validation. +No CI wait, consumer installation check, hosted page, or extra human sign-off +enters the completion path. + +A small `releasekit.json` profile supplies ConfigKit's product identity, +`origin`, the expected authoritative push URL, and the selected shared Go +validation: race, full vet, and package compilation for `linux/amd64` and +`linux/arm64`. It declares no executable build or delivery. macOS remains +best effort. ReleaseKit's other optional checks, including formatting, +Markdown, module-distribution, and file-size checks, remain unselected unless +a separate decision establishes a distinct need for them. + +The release tool is selected at a known version and prepared before offline +candidate validation. The `go` executable used by ReleaseKit must be a +maintained Go 1.25 patch with native race prerequisites available: ReleaseKit +sets `GOTOOLCHAIN=local` for its child commands, so ConfigKit's existing +`CONFIGKIT_BASELINE_TOOLCHAIN` environment selection cannot serve as the +validation mechanism. Dependency and tool preparation may use the network; +candidate validation remains offline and readonly. + +ReleaseKit owns generic candidate guards, test and compile coordination, tag +creation, publication, and push recovery. ConfigKit owns version selection, +compatibility review, note content, its selected validation and support +targets, and a small integration check of its ReleaseKit configuration. The +release process adds no ConfigKit public API or runtime use of ReleaseKit. + +## Changes from the baseline + +- Add the minimal profile and a documented, versioned tool-preparation method. + Keep the selected release command small and do not re-create generic Git + guards or Go check sequencing in a wrapper. +- Revise the [release policy](../policy/release.md) and + [maintainer procedure](../release.md) for candidate publication to `main` + before ReleaseKit's command, its effective-push-URL check, toolchain + preparation, one selected validation pass, tag-only publication, and + ReleaseKit's failure states. Preserve ConfigKit's source-only deliverables, + compatibility rules, supported targets, and no-CI completion rule. +- Update the [development guide](../development.md) so its release guidance and + task-to-test map describe the adopted process. Keep ordinary development + checks separate from release gates; review other references to the retired + scripts. +- Retire `scripts/release.sh`, `scripts/release-check.sh`, and their duplicated + publication and gate tests once ReleaseKit takes over. Preserve the + development-check behavior and its tests from `release_check_test.go`. + Retain only a proportionate ConfigKit integration test for the selected + profile and invocation where it detects a real wiring error. +- Verify the migration without publishing a real ConfigKit version: exercise + the selected profile and release command against an isolated candidate and + temporary Git remote, including a validation failure and successful tag + publication. Confirm the maintained Go 1.25 patch runs the selected gates + once. Do not make a separate successful CI run a release condition. + +Historical tags and release notes remain unchanged. This adoption work does +not itself authorize publication of a ConfigKit version. + +## Open Decisions + +### How should ConfigKit pin and acquire ReleaseKit? + +**Recommendation:** Use a separately installed ReleaseKit executable pinned to +v0.2.0 for the first migration, and document acquisition before offline +validation. ConfigKit has no hosted-delivery workflow to coordinate with a CI +tool pin, so this keeps ReleaseKit and its tool dependencies out of ConfigKit's +library module graph. The [OSS policy](../policy/oss.md) does not require an +attribution entry merely for using a development tool. + +**Viable alternative:** Declare ReleaseKit in ConfigKit's `go.mod` and use its +module-selected tooling convention. This gives local publication and any future +tag-triggered delivery one version declaration, but adds tool dependencies to +the library's module graph and requires dependency and attribution review. + +### Should ConfigKit keep its stricter local publication guards? + +**Recommendation:** Adopt ReleaseKit's note-heading rule and exact +`expected_push_url` check, while continuing to write notes as +`# ConfigKit `. Update policy wording to match the actual automated +guards. ReleaseKit checks the effective publication endpoint and queries that +endpoint for remote state; retaining a second ConfigKit-specific fetch-URL and +exact-heading checker would preserve local release machinery for little added +value. + +**Viable alternative:** Retain small product checks for ConfigKit's exact +first-line title and both configured fetch and push URLs. This preserves the +current local policy literally, but makes ConfigKit continue owning and testing +release-specific checks alongside ReleaseKit's standard guards. + +### Must the release command list skipped filesystem tests? + +**Recommendation:** Treat per-test skip output as optional diagnostic detail +and revise the runbook's statement that the release checker reports it. +ReleaseKit's single standard suite is not verbose, while failed tests still +block publication. This avoids an extra test run solely for output. + +**Viable alternative:** Ask ReleaseKit for a supported verbosity selection +within its one base test invocation. This preserves the current skip display +without duplicating the suite, but expands the shared API and may add output +that other consumers do not need.