145 lines
6.9 KiB
Markdown
145 lines
6.9 KiB
Markdown
# 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.
|
|
|
|
## 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.
|
|
|
|
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 the Candidate
|
|
|
|
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.
|
|
|
|
End each new note with these links, substituting the selected release version 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:
|
|
|
|
```sh
|
|
bash scripts/release.sh --publish v0.2.0
|
|
```
|
|
|
|
This single invocation:
|
|
|
|
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:
|
|
|
|
```sh
|
|
bash scripts/release.sh --check v0.2.0
|
|
```
|
|
|
|
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.
|
|
|
|
## Artifact Delivery
|
|
|
|
[Woodpecker](../.woodpecker/release.yml) runs on tag events. It invokes
|
|
[scripts/build-release.sh](../scripts/build-release.sh), then publishes:
|
|
|
|
- `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:
|
|
|
|
```sh
|
|
git rev-parse 'v0.2.0^{commit}'
|
|
git ls-remote origin refs/heads/main refs/tags/v0.2.0
|
|
```
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
**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.
|
|
|
|
**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.
|
|
|
|
## Maintaining the Release Workflow
|
|
|
|
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.
|