168 lines
7.0 KiB
Markdown
168 lines
7.0 KiB
Markdown
# Releasing Narratio
|
|
|
|
This is the maintainer runbook for the [Release Policy](policy/release.md).
|
|
Its [explicit exceptions](policy/release.md#policy-exceptions) preserve the
|
|
successful tag push as the automated responsibility boundary. Binary publication
|
|
is asynchronous; later consumer-facing inspection is optional.
|
|
|
|
## Prerequisites and publication scope
|
|
|
|
Use a checkout on `main` with Git authentication permitting fetches and pushes
|
|
to `origin`, the authoritative Git remote. Install Git, a POSIX shell, standard
|
|
Unix build tools, and the Go toolchain below. Make required modules available
|
|
before offline validation. No model/provider credentials are needed. Gitea
|
|
publication credentials belong to CI's secret store, not the local command.
|
|
|
|
Synchronous guards inspect local tags and `origin`, not every configured remote
|
|
or Gitea release entry. Do not select a version known to have been published in
|
|
any channel, even if these guards cannot see it.
|
|
|
|
## Go prerequisite
|
|
|
|
Release preparation requires the maintained Go 1.26 baseline. Tag CI currently
|
|
uses the explicitly pinned `golang:1.26.7` image for validation and asset builds.
|
|
That asynchronous work does not change the tag-push completion boundary.
|
|
|
|
## Choose a version and write its note
|
|
|
|
Select an unused stable version under the
|
|
[versioning rules](policy/release.md#versioning-and-compatibility). Narratio is
|
|
past v1.0.0; intentional CLI/configuration breaks require a major release.
|
|
|
|
Create `docs/releases/vMAJOR.MINOR.PATCH.md` using the
|
|
[required note structure](policy/release.md#release-documentation).
|
|
Describe CLI, configuration, artifact, integration, and operating-contract
|
|
changes, and the required operator action. Link to current canonical
|
|
documentation for exact behavior.
|
|
|
|
## Prepare and record the candidate
|
|
|
|
Before committing, perform these manual reviews in addition to automated checks:
|
|
|
|
- Confirm compatibility/version selection and update affected canonical
|
|
documentation and maintained examples.
|
|
- Remove completed roadmap documents covering work included in this release;
|
|
retain pending work. Their history remains in Git. Do not delete historical
|
|
release notes.
|
|
- Review the diff, staged changes, and untracked files for credentials, private
|
|
data, generated output, unintended files, and unrelated changes.
|
|
- Review changed documentation links and behavior-bearing commands. Automated
|
|
link checks supplement rather than replace review.
|
|
|
|
Commit the note and candidate changes, then push that commit to `main` through
|
|
the ordinary development workflow. Record the exact candidate:
|
|
|
|
```sh
|
|
git rev-parse HEAD
|
|
```
|
|
|
|
Do not create a tag until `origin/main` points to that same commit. If the
|
|
candidate changes, repeat the reviews and validation.
|
|
|
|
## Validate the candidate
|
|
|
|
From the repository root, run:
|
|
|
|
```sh
|
|
scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH
|
|
```
|
|
|
|
The script also works when invoked by its absolute path from another directory.
|
|
It validates the version and matching note, module hygiene, formatting,
|
|
whitespace, uncached tests, race tests, static checks, documentation, examples,
|
|
and three cross-build assets. It uses `GOWORK=off`, does not contact application
|
|
services, CI, or Gitea, and does not create tags or modify tracked source.
|
|
Fix failures on `main`, commit, push normally, and rerun validation.
|
|
|
|
The macOS cross-build proves compilation, not native runtime behavior.
|
|
|
|
## Declared deliverables and automation
|
|
|
|
The source release is the exact version tag at the validated commit.
|
|
The tag-triggered `.woodpecker/release.yml` validates the tagged source,
|
|
runs `scripts/build-release-assets.sh`, and publishes these Gitea assets:
|
|
|
|
- `narratio-vMAJOR.MINOR.PATCH-linux-amd64`
|
|
- `narratio-vMAJOR.MINOR.PATCH-linux-arm64`
|
|
- `narratio-vMAJOR.MINOR.PATCH-darwin-arm64` (best effort)
|
|
- `SHA256SUMS`
|
|
|
|
The builder embeds the version, disables ambient Go workspaces, and checks a
|
|
host binary's `version` output. The release publisher uses the matching
|
|
checked-in note and generates SHA-256 checksums. Existing files are skipped and
|
|
overwrite is disabled. No image or package-registry deliverable is declared.
|
|
CI does not choose versions, modify source candidates, or move tags.
|
|
|
|
## Publish the tag
|
|
|
|
From a clean checkout on `main` whose `HEAD` equals `origin/main`, run:
|
|
|
|
```sh
|
|
scripts/release.sh vMAJOR.MINOR.PATCH
|
|
```
|
|
|
|
The command fetches and checks `origin/main`, re-runs candidate validation,
|
|
then fetches and checks again before creating an explicitly unsigned lightweight
|
|
tag for the originally recorded commit. It refuses dirty, divergent, changed,
|
|
or already-tagged candidates. It verifies the local tag target and pushes only:
|
|
|
|
```text
|
|
refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH
|
|
```
|
|
|
|
It never commits changes, pushes `main`, force-pushes, moves tags, or pushes all
|
|
tags. Successful publication of that ref completes the command; it prints the
|
|
tag and commit and returns without waiting for CI, querying Gitea, downloading
|
|
assets, or checking checksums.
|
|
|
|
## Failure handling
|
|
|
|
Before tag creation, correct the candidate on `main` and repeat validation.
|
|
If a push fails after local tag creation, the local tag is retained for inspection.
|
|
Do not retry blindly or assume the remote received nothing: a connection failure
|
|
can leave publication uncertain. Inspect the exact remote ref before taking any
|
|
local-tag cleanup action. This is recovery from a failed command, not a
|
|
post-success publication gate.
|
|
|
|
After publication, follow the
|
|
[immutability and correction rules](policy/release.md#immutability-and-correction).
|
|
Correct defects or failed asynchronous publication with a new semantically
|
|
appropriate version, matching note, and the complete procedure. Never replace
|
|
existing tagged assets in place.
|
|
|
|
## Optional asynchronous inspection
|
|
|
|
A human may later inspect the tag-triggered Woodpecker job and Gitea release.
|
|
This is optional follow-up, never part of the automated releaser's completion
|
|
criteria. Do not wait for or poll CI/Gitea from the release command.
|
|
|
|
For optional source verification, substitute the released version below and
|
|
compare the remote target to the recorded candidate hash:
|
|
|
|
```sh
|
|
git ls-remote --tags origin refs/tags/vMAJOR.MINOR.PATCH
|
|
git rev-parse 'refs/tags/vMAJOR.MINOR.PATCH^{commit}'
|
|
```
|
|
|
|
Download the three named binaries and `SHA256SUMS` from the matching Gitea release
|
|
into an empty inspection directory. In that directory, verify on Linux:
|
|
|
|
```sh
|
|
sha256sum --check SHA256SUMS
|
|
```
|
|
|
|
On macOS, use `shasum -a 256 --check SHA256SUMS`. After successful verification,
|
|
make the matching host binary executable and run its version command, for example
|
|
on Linux amd64 (replace the version in both commands):
|
|
|
|
```sh
|
|
chmod +x ./narratio-vMAJOR.MINOR.PATCH-linux-amd64
|
|
./narratio-vMAJOR.MINOR.PATCH-linux-amd64 version
|
|
```
|
|
|
|
Expected output is `narratio vMAJOR.MINOR.PATCH`. Use only the matching architecture
|
|
on other supported hosts. Checksums establish consistency with the downloaded
|
|
checksum file, not a new signature or independent authenticity guarantee.
|
|
Missing assets are an asynchronous publication problem, not grounds to move or
|
|
reuse the successfully published source tag.
|