127 lines
7.2 KiB
Markdown
127 lines
7.2 KiB
Markdown
# Single-Command Release Workflow and Gate Review
|
|
|
|
Status: implemented on 2026-09-28. The
|
|
[implementation plan](implementation.md) records the completed work and checks.
|
|
|
|
## Intent and baseline
|
|
|
|
Make source releases simple for humans and agents: one publication command
|
|
validates the final committed candidate, checks publication state, and publishes
|
|
only the intended refs. Keep the minimum gates justified by ConfigKit's actual
|
|
risks, with no routine human intervention or waiting for CI.
|
|
|
|
Local baseline: `0adb94f59e44827908eff401d4381a398fe17107` (v0.4.1).
|
|
The upstream reference is release policy v1.4 at
|
|
`d84a38ebab26f048cafbe59a2246700c35d29843`:
|
|
[standard release policy](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md).
|
|
|
|
At the planning baseline, `scripts/release-check.sh` performed local validation; the runbook separately
|
|
records a candidate commit and executes shell blocks for guards, branch push,
|
|
annotated tagging, and tag push. The checker runs module hygiene, formatting and
|
|
whitespace checks, one race-enabled suite, vet, and Linux amd64/arm64 cross-builds
|
|
using a maintained Go 1.25 patch. Publication completes on successful tag push.
|
|
|
|
The implementation plan records the subsequent gate selection and publication
|
|
command. Current requirements belong to the
|
|
[release policy](../policy/release.md) and [runbook](../release.md).
|
|
|
|
## Target release contract
|
|
|
|
ConfigKit remains a source-only Go module hosted at its authoritative Gitea
|
|
remote. Releases identify a final committed source revision on `main`, one fresh
|
|
immutable annotated version tag, and a matching checked-in release note.
|
|
No binary distribution, hosted release object, or registry publication is added.
|
|
|
|
The publication command owns validation, candidate identity, guards, and explicit
|
|
ref publication. Preparation still supplies the version, committed release note,
|
|
and dependencies/toolchain; the command must not silently edit or commit source,
|
|
choose a version, or upgrade dependencies. Publication remains subject to user
|
|
authorization, not the standing local-commit policy.
|
|
|
|
The command validates the exact candidate once. An optional validation-only mode
|
|
may support diagnosis but is not a prerequisite followed by duplicate validation.
|
|
Do not require both everyday and release checkers. An implementation need not
|
|
introduce a persistent validation cache merely to replace the former manual record.
|
|
|
|
Mechanical guards ensure a clean worktree/index on the primary branch, an unused
|
|
valid version locally and on the authoritative remote, a matching release note,
|
|
and exact agreement between validated source and tagged source. Publish only
|
|
intended refs without discarding remote history. Ignored local files are not
|
|
release content and do not alone prevent publication.
|
|
|
|
A successful intended tag push, with the source commit available on authoritative
|
|
main, completes the release. Never wait for or poll CI, module availability,
|
|
consumer installation, or optional verification. Do not add a successful-push
|
|
remote read-back gate. If future artifact channels are adopted, delivery status
|
|
must remain separate; this task introduces none.
|
|
|
|
## Selected gate rationale
|
|
|
|
Keep the full deterministic offline suite as the core check. The selected gates
|
|
below provide distinct protection without repeating validation. Their rationale
|
|
belongs in the adopted release policy, with commands in the runbook and tooling.
|
|
|
|
| Check | Selected end state and rationale |
|
|
| --- | --- |
|
|
| Race detector | One full race-enabled suite protects ownership and concurrent loads; no second ordinary suite. |
|
|
| Vet | One full vet pass provides additional static analysis; disable the smaller test-time vet pass to avoid overlap. |
|
|
| Module hygiene | Tidiness belongs to dependency-change review, not a recurring release audit. Offline tests/builds use readonly module mode to avoid incidental manifest edits. |
|
|
| Formatting and whitespace | Ordinary development checks, not publication gates; the everyday checker remains unchanged. |
|
|
| Linux amd64/arm64 builds | Retain both CGO-disabled builds: they cover supported configurations distinct from native race compilation. |
|
|
| Toolchain selection | One maintained Go 1.25 patch, with no second-toolchain gate or per-release latest-version research. |
|
|
|
|
Examples, consumer fixtures, documentation links, and import/public boundary tests
|
|
are already in the suite; they must not become separately repeated release checks.
|
|
macOS remains best-effort. No human sign-off, new linter, hardware requirement,
|
|
scanner, credentials-dependent test, or remote application probe is introduced.
|
|
|
|
## Documentation and recovery
|
|
|
|
Align `docs/policy/release.md` with upstream shared wording, preserving explicit
|
|
ConfigKit decisions and the selected gate rationale. The successful-tag-push rule
|
|
is a normal supported choice under the new upstream policy, not an exception
|
|
requiring newly invented compensating controls.
|
|
|
|
Make `docs/release.md` a short executable runbook for preparation and the single
|
|
command. New notes use a proportionate summary and applicable compatibility and
|
|
upgrade information rather than mandatory empty sections. Preserve the licensing
|
|
footer and version-specific immutable links. Derive annotated-tag summary content
|
|
from the checked-in note. Keep historical notes unchanged.
|
|
|
|
Validation or guard failure stops publication with actionable diagnostics and no
|
|
force updates. A failed or ambiguous push requires resolving authoritative remote
|
|
state before retrying or reporting success. A transient failure does not itself
|
|
require a new version. Published tags remain immutable; removing an unpublished
|
|
local tag requires confirmation it was never published. Explain partial progress
|
|
such as a successful branch push followed by a failed tag push.
|
|
|
|
## Changes needed and scope
|
|
|
|
The work affects `docs/policy/release.md`, `docs/release.md`, release shell tooling,
|
|
`release_check_test.go`, and relevant contributor guidance. Reuse existing
|
|
validation mechanisms where appropriate; avoid a general release framework.
|
|
Tests should exercise success and meaningful failure/recovery paths in disposable
|
|
local repositories, without real publication or credentials. Match coverage to
|
|
the chosen push strategy and protect against unintended refs or stale candidates.
|
|
|
|
Preserve provenance and licensing established by the completed
|
|
[policy roadmap](policy.md).
|
|
Operational documentation changes land with the implementation they describe.
|
|
No library behavior, dependency update, release tag, or push is authorized by
|
|
implementing this roadmap alone.
|
|
|
|
## Publication strategy
|
|
|
|
Use explicit main-then-tag pushes inside the command. This matches the proven
|
|
local workflow and avoids a new dependency on atomic-push support. A branch-only
|
|
intermediate result is possible; recovery distinguishes it from completed or
|
|
unknown publication. Atomic publication is not part of this target.
|
|
|
|
## Completion criteria
|
|
|
|
One documented command publishes a prepared candidate with the reviewed minimum
|
|
gate set, no duplicate suite runs, and automated exact-source safeguards. Local
|
|
regression tests demonstrate successful publication and safe failure handling.
|
|
The policy, runbook, and scripts agree, and successful tag publication is reported
|
|
without waiting for external completion evidence.
|