Document the ReleaseKit release workflow
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
# Architectural Decision Records
|
||||
|
||||
No ADRs have been recorded here. Use the
|
||||
## Accepted
|
||||
|
||||
- [ADR 0001: Adopt ReleaseKit for release management](0001-releasekit.md) —
|
||||
accepted 2026-10-07.
|
||||
|
||||
Use the
|
||||
[documentation policy's ADR lifecycle](../policy/documentation.md#architecture-decision-records)
|
||||
for significant decisions. Current architecture belongs in the
|
||||
[architecture policy](../policy/architecture.md); implementation status belongs in
|
||||
|
||||
10
docs/cli.md
10
docs/cli.md
@@ -11,6 +11,7 @@ the [migration guide](migrations/v2.md) maps retired inputs.
|
||||
audita process <transcript.json> --glossary <glossary.yml> [flags]
|
||||
audita config validate --config <config.yml> [flags]
|
||||
audita config print-effective [flags]
|
||||
audita version
|
||||
```
|
||||
|
||||
Root invocation, `--help`, `-h`, and command help succeed without loading a config
|
||||
@@ -26,6 +27,15 @@ Missing system candidates are skipped; inaccessible selected files are errors.
|
||||
No file means a configuration error. `AUDITA_CONFIG` is ignored. The selected
|
||||
overlay is loaded beside the main file, not used to locate profile files.
|
||||
|
||||
`audita version` prints `audita <version>` and a newline to stdout, with no
|
||||
application configuration or provider setup. It returns `0` on success with
|
||||
empty stderr. `help version`, `version -h`, and `version --help` print command
|
||||
usage to stdout and return `0`; unexpected arguments and unknown flags return
|
||||
`2` with a usage error on stderr. The command uses ReleaseKit's public
|
||||
`buildinfo.Version()` accessor. It reports an injected release identifier when
|
||||
present, otherwise the executable's main-module version when available and not
|
||||
`(devel)`, and `dev` when neither source provides a release identifier.
|
||||
|
||||
## Setting overrides
|
||||
|
||||
Only flags actually supplied override file or overlay settings. `--modules ''`
|
||||
|
||||
@@ -27,6 +27,11 @@ CLI wiring, and maintained examples. Definitions of behavior belong to the
|
||||
for the changed behavior.
|
||||
4. Update the CLI reference and affected integration guidance.
|
||||
|
||||
The `version` route uses ReleaseKit's public `buildinfo.Version()` accessor and
|
||||
stays independent of application runtime assembly. Preserve its behavior from
|
||||
the [CLI contract](../cli.md#commands-and-help) when changing the command; the
|
||||
adoption decision is recorded in [ADR 0001](../adr/0001-releasekit.md).
|
||||
|
||||
## Validating Examples
|
||||
|
||||
Keep complete copyable files in [examples](../../examples/) and link to them from
|
||||
|
||||
@@ -28,6 +28,20 @@ License and notices: [LGPL v3](licenses/LGPL-3.0.txt) |
|
||||
|
||||
[Source](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/dc09959cca4e105f49ec316c6d4ba585bd2340bd).
|
||||
|
||||
## ReleaseKit
|
||||
|
||||
Selected module: `gitea.maximumdirect.net/eric/ReleaseKit` at `v0.1.0`.
|
||||
|
||||
Copyright (C) 2026 Eric Rakestraw
|
||||
|
||||
SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
License and notices: [LGPL v3](licenses/LGPL-3.0.txt) |
|
||||
[GPL v3](licenses/GPL-3.0.txt) |
|
||||
[COPYRIGHT](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/COPYRIGHT).
|
||||
|
||||
[Source](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1).
|
||||
|
||||
## Go runtime and standard library
|
||||
|
||||
Selected toolchain: Go 1.25.5 for the distributed Linux binaries.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Base Policy Version:** 1.4
|
||||
|
||||
**Last Updated**: 2026-09-28
|
||||
**Last Updated**: 2026-10-07
|
||||
**Upstream Source:** [Standard Repository Policies release](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md)
|
||||
|
||||
## Purpose
|
||||
@@ -49,12 +49,17 @@ failures and optional investigations under artifact-delivery status.
|
||||
| --- | --- |
|
||||
| Linux amd64 | Required production target |
|
||||
| Linux arm64 | Required production target |
|
||||
| macOS arm64 | Best effort for local development; failures do not block a release or Linux artifact publication |
|
||||
| macOS arm64 | Best effort for local development; development failures do not block a release or Linux artifact publication |
|
||||
|
||||
Windows and macOS amd64 are unsupported. Neither their builds nor tests are
|
||||
release requirements. Native macOS testing and access to a Mac are not release
|
||||
prerequisites.
|
||||
|
||||
Linux amd64 and arm64 remain the required production targets. Publication from
|
||||
a host outside the selected target set must pass ReleaseKit's temporary native
|
||||
version check. This check does not require access to a Mac or native tests on
|
||||
every delivery target.
|
||||
|
||||
## Versioning And Compatibility
|
||||
|
||||
Stable releases use Semantic Versioning in the form `vMAJOR.MINOR.PATCH`, with
|
||||
|
||||
186
docs/release.md
186
docs/release.md
@@ -1,144 +1,120 @@
|
||||
# Releasing Audita
|
||||
|
||||
The [release policy](policy/release.md) defines versioning, supported platforms,
|
||||
immutability, and success. This runbook implements it with
|
||||
[scripts/release.sh](../scripts/release.sh). Publication ends after a successful
|
||||
source/tag push; binary delivery runs asynchronously.
|
||||
The [release policy](policy/release.md) owns release requirements. This runbook
|
||||
uses the native commands in [scripts/release.sh](../scripts/release.sh), which
|
||||
builds and invokes ReleaseKit. A confirmed source tag completes the release;
|
||||
Woodpecker reports binary delivery separately.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Use Bash, Git, and Go 1.25.5 or newer (CI uses Go 1.25.5), with dependencies
|
||||
available locally or downloadable. Tests themselves are offline. Work from a
|
||||
checkout of `main` with permission to push that branch and tags to `origin`.
|
||||
For this repository, `origin` is `https://gitea.maximumdirect.net/eric/audita.git`.
|
||||
The script uses the checkout's configured `origin`; set it correctly before use.
|
||||
The remote must support atomic pushes. No CI credentials or Mac are needed locally.
|
||||
Use Bash, Git, and Go 1.25.5 or newer. The authoritative remote is `origin`,
|
||||
which must point to `https://gitea.maximumdirect.net/eric/audita.git`; the
|
||||
primary branch is `main`. Source publication needs no delivery credential.
|
||||
Woodpecker uses the existing `GITEA_RELEASE_TOKEN` secret for delivery.
|
||||
|
||||
CI uses the existing `GITEA_RELEASE_TOKEN` secret for asynchronous asset delivery.
|
||||
macOS arm64 is a best-effort development environment; no macOS binary is published.
|
||||
Prepare dependencies before offline candidate validation:
|
||||
|
||||
## Prepare the Candidate
|
||||
```sh
|
||||
GOWORK=off GOTOOLCHAIN=local go mod download
|
||||
```
|
||||
|
||||
Choose an unused version following the policy. Write
|
||||
`docs/releases/<version>.md`, beginning with `# Audita <version>`, followed by a
|
||||
short summary and any compatibility or upgrade instructions relevant to the
|
||||
release. There are no mandatory boilerplate sections. Update affected canonical
|
||||
documentation with behavior changes.
|
||||
If dependency preparation changes `go.mod` or `go.sum`, include those changes in
|
||||
the committed candidate. The release wrapper separately bootstraps the pinned
|
||||
ReleaseKit command into ignored `bin/releasekit`; that build is tool preparation,
|
||||
not candidate validation.
|
||||
|
||||
End each new note with these links, substituting the selected release version for
|
||||
`<version>`:
|
||||
## Prepare and publish the candidate
|
||||
|
||||
Choose an unused version under the [release policy](policy/release.md), write
|
||||
`docs/releases/<version>.md`, and begin it with `# Audita <version>`. Include a
|
||||
short summary, relevant compatibility or upgrade instructions, and the required
|
||||
`COPYRIGHT | LICENSE | ATTRIBUTION` footer with links for the selected version.
|
||||
Update affected canonical documentation with behavior changes.
|
||||
|
||||
End each note with this footer, substituting its complete tag for `<version>`:
|
||||
|
||||
```markdown
|
||||
[COPYRIGHT](https://gitea.maximumdirect.net/eric/audita/src/tag/<version>/COPYRIGHT) | [LICENSE](https://gitea.maximumdirect.net/eric/audita/src/tag/<version>/LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/audita/src/tag/<version>/docs/oss/attribution.md)
|
||||
```
|
||||
|
||||
Check that all three paths exist in the candidate source. Retire completed
|
||||
roadmaps when useful during preparation, preserving planned and deferred work
|
||||
and repairing affected links. This is ordinary preparation, not a script gate.
|
||||
|
||||
Commit the intended changes, including the note, on `main`. The release script
|
||||
requires a clean index and worktree and does not create commits. There is no
|
||||
separate approval round. Published notes describe their tagged release; existing
|
||||
release history does not need to be reconstructed.
|
||||
|
||||
## Validate and Publish
|
||||
|
||||
From the repository root, substitute the chosen version:
|
||||
Commit the complete candidate on `main`, including the release note, then push
|
||||
the branch first:
|
||||
|
||||
```sh
|
||||
bash scripts/release.sh --publish v0.2.0
|
||||
git push origin main
|
||||
```
|
||||
|
||||
This single invocation:
|
||||
Record the candidate commit. Before publication, remote `main` must identify
|
||||
that exact commit. ReleaseKit checks this along with the clean candidate, note,
|
||||
version, and remote tag state.
|
||||
|
||||
1. Checks the version, branch, clean candidate, matching note title, and tag absence.
|
||||
2. Runs the default offline test suite once, then builds both required Linux targets
|
||||
in a temporary directory using the same build script as CI.
|
||||
3. Checks that the candidate and worktree are unchanged and that it includes the
|
||||
current `origin/main` history.
|
||||
4. Creates the version tag at that commit and atomically pushes the exact source
|
||||
commit to `main` and the exact tag to `origin`.
|
||||
5. Reports release success and exits without polling CI or checking asset availability.
|
||||
|
||||
To validate a prepared candidate without remote access, creating a tag, or pushing:
|
||||
Publish from the repository root, substituting the selected version:
|
||||
|
||||
```sh
|
||||
bash scripts/release.sh --check v0.2.0
|
||||
bash scripts/release.sh publish VERSION
|
||||
```
|
||||
|
||||
This is an optional diagnostic command, not a required step before `--publish`.
|
||||
Publication validates within its own invocation; it does not use persistent cached
|
||||
results. Both modes require the candidate note and a clean `main` checkout.
|
||||
The command runs `go test -mod=readonly -count=1 ./...` once with module and
|
||||
toolchain network access disabled, builds the profile's Linux amd64 and arm64
|
||||
targets, and checks the native version output. It creates an annotated tag whose
|
||||
message comes from the committed note, then pushes the exact tag object. A
|
||||
successful publication completes the source release without waiting for CI or
|
||||
checking artifact availability.
|
||||
|
||||
## Artifact Delivery
|
||||
`bash scripts/release.sh check VERSION` is an optional local diagnostic. It
|
||||
does not inspect remote availability or publish a tag, and it is not a required
|
||||
step before `publish`, which performs its own candidate validation.
|
||||
|
||||
[Woodpecker](../.woodpecker/release.yml) runs on tag events. It invokes
|
||||
[scripts/build-release.sh](../scripts/build-release.sh), then publishes:
|
||||
The wrapper preserves ReleaseKit's exit status: `0` means confirmed publication;
|
||||
`1` means a known validation or publication failure/conflict; `2` means usage,
|
||||
profile, or version input error; and `3` means the push outcome remains unknown.
|
||||
|
||||
## Binary delivery
|
||||
|
||||
Woodpecker runs the pinned ReleaseKit `ci-deliver` command for tags under
|
||||
`refs/tags/v*`. It verifies the triggering commit against the tag, prepares the
|
||||
tagged source, and uses `releasekit.json` to build and deliver:
|
||||
|
||||
- `audita-<version>-linux-amd64`
|
||||
- `audita-<version>-linux-arm64`
|
||||
- `SHA256SUMS`
|
||||
|
||||
Builds disable CGO and use the shared script's release flags. The version is in the
|
||||
asset name and source tag; Audita has no CLI version command. Cross-compilation
|
||||
checks compilation, not native execution on each architecture.
|
||||
|
||||
The CI job status and logs show delivery progress or failure. Assets appear on
|
||||
the matching Gitea release page when delivery succeeds. A successful tag push
|
||||
must not be reported as confirmation that these files are available.
|
||||
For a new hosted release, the release plugin uses the checked-in note at the
|
||||
tag as its body, including the footer. On delivery retries it preserves
|
||||
existing release information and skips files that already exist.
|
||||
|
||||
Consumers can download the binary for their Linux architecture and `SHA256SUMS`
|
||||
from that page, check its listed SHA-256 digest with `sha256sum`, and make it
|
||||
executable. Optional consumer checks are not maintainer release gates. Digests
|
||||
detect file mismatches; they are not an independent signature of authenticity.
|
||||
|
||||
## Failure and Retry
|
||||
|
||||
**Local validation fails:** correct the issue, commit any changes, and rerun the
|
||||
publication command. A failure before tag creation publishes nothing. Temporary
|
||||
local build files are removed on exit.
|
||||
|
||||
**Push fails or the connection is interrupted:** the script retains the local tag
|
||||
and reports failure rather than guessing whether publication succeeded. Inspect
|
||||
remote state with the actual version:
|
||||
The workflow invokes:
|
||||
|
||||
```sh
|
||||
git rev-parse 'v0.2.0^{commit}'
|
||||
git ls-remote origin refs/heads/main refs/tags/v0.2.0
|
||||
go run gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@${RELEASEKIT_VERSION} ci-deliver \
|
||||
--repo "$${CI_WORKSPACE}" \
|
||||
--commit "$${CI_COMMIT_SHA}" \
|
||||
"$${CI_COMMIT_TAG}"
|
||||
```
|
||||
|
||||
If the remote tag identifies the intended candidate and its source is on remote
|
||||
`main`, the release succeeded; no CI waiting is needed. An atomic push normally
|
||||
updates both refs or neither. If `main` has advanced since publication, fetch it
|
||||
and check candidate ancestry rather than requiring tip equality.
|
||||
Woodpecker sets `RELEASEKIT_VERSION` to `v0.1.0` for this workflow.
|
||||
|
||||
If the tag is absent remotely and was never published or used by a release
|
||||
channel, remove only that unpublished local tag (`git tag -d v0.2.0`), resolve
|
||||
any rejected branch update, and rerun the command. If the remote tag has a
|
||||
different target, do not overwrite it; choose a fresh version. Never force a
|
||||
branch or tag update to bypass the guards.
|
||||
The complete checked-in release note, including its licensing footer, supplies
|
||||
the hosted release body. The workflow maps the existing `GITEA_RELEASE_TOKEN`
|
||||
secret to `RELEASEKIT_GITEA_TOKEN`. Delivery runs independently after source
|
||||
publication; its status and logs report delivery progress or failure.
|
||||
|
||||
**CI delivery fails:** the release remains successful. Inspect the failed tag
|
||||
job's logs and retry that same tagged job for a transient failure. Publication is
|
||||
configured to skip existing filenames and not overwrite assets. Keep the same
|
||||
source and build environment when retrying; inspect any existing assets/checksum
|
||||
manifest before filling gaps. Do not regenerate and replace a published manifest
|
||||
or binary. If an existing manifest cannot describe the missing rebuilt assets,
|
||||
use a new version instead. A pipeline or source defect also requires a corrected
|
||||
commit and new version. An outage does not require moving the tag.
|
||||
ReleaseKit handles content-aware retries and retained-artifact recovery. See
|
||||
the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md)
|
||||
and [delivery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md)
|
||||
for those mechanics. A delivery failure does not undo a confirmed source
|
||||
release. Retry the same immutable tag after resolving the reported state; do not
|
||||
replace published files or a checksum manifest.
|
||||
|
||||
**A released source defect is discovered:** fix it on `main` and publish a new
|
||||
appropriate version with a note explaining the correction. Leave the old tag and
|
||||
published files intact.
|
||||
## Failure and recovery
|
||||
|
||||
## Maintaining the Release Workflow
|
||||
Fix validation failures in a new committed candidate, then rerun `publish`.
|
||||
After a failed push, ReleaseKit retains the local annotated tag and reports the
|
||||
captured authoritative endpoint and publication state. Resolve the result
|
||||
against that endpoint before retrying. An exact remote tag-object match, with
|
||||
its source available on remote `main`, can confirm publication. If the remote
|
||||
state cannot be read, the result remains unknown; do not remove or replace the
|
||||
tag while uncertain. Follow the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md)
|
||||
for object-level recovery details.
|
||||
|
||||
The shared build script keeps local and CI build settings aligned. Tests in
|
||||
[scripts/release_test.go](../scripts/release_test.go) exercise publication against
|
||||
temporary local Git remotes, including guard failures and rejected pushes, with
|
||||
Go execution stubbed to avoid recursive builds/tests. They run in `go test ./...`.
|
||||
Changes to CI delivery should preserve explicit asset names, checksums, and
|
||||
non-overwriting publication. CI delivery is separate from the local success path.
|
||||
A source-release success and artifact-delivery status are separate. For a
|
||||
partial or uncertain delivery, inspect the job output and follow the pinned
|
||||
[delivery recovery guidance](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md).
|
||||
A source or published-content correction requires a new appropriate version;
|
||||
leave the original tag and its contents intact.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
**Status:** Complete. The implementation and tests are committed through
|
||||
`8175ed8`. Final documentation and example changes were included in the full
|
||||
build, test, example-validation, and local-link checks before the documentation
|
||||
completion commit. The [implementation plan](implementation.md) records the
|
||||
ordered work and verification.
|
||||
completion commit. The [historical implementation plan](https://gitea.maximumdirect.net/eric/audita/src/commit/b31955fc97adec707b4e5f9a1b0c43c4cbc66750/docs/roadmap/implementation.md)
|
||||
records the ordered work and verification.
|
||||
|
||||
## Purpose and Baseline
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Implementation Plan: ReleaseKit Adoption
|
||||
|
||||
**Last updated:** 2026-10-07
|
||||
**Status:** Stages 1–3 complete; Stages 4–5 pending.
|
||||
**Status:** Stages 1–4 complete; Stage 5 pending.
|
||||
**Audience:** Luna coding agent.
|
||||
|
||||
## Scope and Execution
|
||||
@@ -203,9 +203,9 @@ is observed during subsequent delivery, independently of source completion.
|
||||
`ci-deliver` step using the existing secret, then removed the obsolete binary
|
||||
builder. Verified the parsed workflow settings and command against the pinned
|
||||
template, confirmed the module/workflow pins match, ran `go test ./scripts`,
|
||||
checked for active builder references, and passed `git diff --check`.
|
||||
confirmed no active CI or script caller remained, and passed `git diff --check`.
|
||||
|
||||
## Stage 4 — Align Policy, Documentation, and Attribution
|
||||
## Stage 4 — Align Policy, Documentation, and Attribution [x]
|
||||
|
||||
**Primary files:** `docs/release.md`, `docs/policy/release.md`, `docs/cli.md`,
|
||||
`docs/internal/cli-config.md`, `docs/adr/README.md`, and
|
||||
@@ -261,6 +261,12 @@ local links and anchors, pinned upstream references, source attribution, and
|
||||
`git diff --check`. Use the prior successful code checks for unchanged code.
|
||||
Commit the documentation unit.
|
||||
|
||||
**Completed 2026-10-07:** Updated the ReleaseKit runbook, release policy,
|
||||
version contract and contributor guidance, ADR index, and component attribution.
|
||||
Repaired PromptKit and ConfigKit links to their historical implementation
|
||||
records. Verified local links and anchors, release CLI and version commands,
|
||||
pinned module/notices, source attribution, and `git diff --check`.
|
||||
|
||||
## Stage 5 — Verify Adoption and Close the Plan
|
||||
|
||||
**Primary files:** This plan and the ReleaseKit feature roadmap; fix an
|
||||
|
||||
@@ -262,8 +262,8 @@ No live provider calls, new release gates, or CI-success dependency are needed
|
||||
to establish adoption. Guided domain recovery and the other work recorded in
|
||||
[future.md](future.md) remain separate features. Do not expand this upgrade into
|
||||
new report formats, pipeline scheduling, or general configuration-inspection
|
||||
commands. The [implementation plan](implementation.md) owns execution steps
|
||||
and their verification.
|
||||
commands. The [historical implementation plan](https://gitea.maximumdirect.net/eric/audita/src/commit/418da456d75a68d3bb5a43ab823c5b2b434b90cc/docs/roadmap/implementation.md)
|
||||
records that work's execution steps and verification.
|
||||
|
||||
## Completion Record
|
||||
|
||||
|
||||
Reference in New Issue
Block a user