115 lines
5.7 KiB
Markdown
115 lines
5.7 KiB
Markdown
# Releasing Narratio
|
|
|
|
This is the maintainer runbook for the [Release Policy](policy/release.md).
|
|
The source release completes when the intended tag is successfully pushed to
|
|
`origin`; binary delivery is a separate asynchronous status.
|
|
|
|
## Prepare the candidate
|
|
|
|
Use `main` and the authoritative Git remote `origin`. Install Git, a POSIX
|
|
shell, standard Unix build tools, and Go 1.26. Have the selected Go modules
|
|
available before offline validation. Git access must permit fetch and tag push.
|
|
Application-provider credentials are not required; Gitea delivery credentials
|
|
belong to CI.
|
|
|
|
Choose an unused stable `vMAJOR.MINOR.PATCH` under the
|
|
[compatibility rules](policy/release.md#versioning-and-compatibility). Narratio
|
|
is past v1.0.0, so intentional CLI or configuration breaks require a major
|
|
release. Update affected canonical documentation with the change. Write the
|
|
matching `docs/releases/vMAJOR.MINOR.PATCH.md` with a short summary and any
|
|
relevant compatibility impact or upgrade action; choose sections to suit the
|
|
release.
|
|
|
|
End that checked-in note with these three links, replacing the version in
|
|
each URL with the intended tag. The tag need not exist remotely yet. Check that
|
|
`COPYRIGHT`, `LICENSE`, and `docs/oss/attribution.md` are present in the
|
|
candidate. The tag CI reuses the checked-in note as the hosted release body.
|
|
|
|
```markdown
|
|
[COPYRIGHT](https://gitea.maximumdirect.net/eric/narratio/src/tag/vMAJOR.MINOR.PATCH/COPYRIGHT) | [LICENSE](https://gitea.maximumdirect.net/eric/narratio/src/tag/vMAJOR.MINOR.PATCH/LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/narratio/src/tag/vMAJOR.MINOR.PATCH/docs/oss/attribution.md)
|
|
```
|
|
|
|
Retire completed roadmaps included in the release while preserving planned or
|
|
deferred work and repairing affected links. Review the change through the
|
|
ordinary development workflow for unintended files, credentials, private data,
|
|
and documentation accuracy. Commit and push the candidate to `origin/main`
|
|
before tagging; record its exact commit if needed:
|
|
|
|
```sh
|
|
git rev-parse HEAD
|
|
```
|
|
|
|
## Publish
|
|
|
|
From a clean `main` checkout at the pushed candidate, run one command:
|
|
|
|
```sh
|
|
scripts/release.sh vMAJOR.MINOR.PATCH
|
|
```
|
|
|
|
It fetches `origin/main` and tags; requires local `HEAD` to equal
|
|
`origin/main`; checks the committed note and unused version; runs the
|
|
candidate checker **once**; then repeats cheap mutable-state guards before
|
|
creating an unsigned lightweight tag at the recorded commit. It verifies the
|
|
tag target and pushes only
|
|
`refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH`. It does not
|
|
commit, push `main`, force updates, or publish all tags.
|
|
|
|
The checker runs `go mod tidy -diff`, tracked Go formatting and diff whitespace
|
|
checks, one `go test -mod=readonly -race -count=1 ./...` full suite, and
|
|
`go vet -mod=readonly ./...`. Its asset builder cross-builds Linux amd64,
|
|
Linux arm64, and best-effort macOS arm64, then checks the embedded version
|
|
on a host binary. The macOS cross-build proves compilation, not native
|
|
runtime behavior. Owned Go commands run with `GOWORK=off`; tests, vet, and
|
|
builds use readonly module mode. The deterministic suite includes documentation
|
|
and maintained-example checks. The command does not contact application
|
|
services or Gitea and does not wait for CI.
|
|
|
|
A successful tag push is the source-release completion point. The command
|
|
prints the tag and commit and exits without a separate network read-back.
|
|
For optional diagnosis before publication, run
|
|
`scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH`; publication will
|
|
validate the candidate again, so this is not a required preparation step.
|
|
|
|
## Artifact delivery
|
|
|
|
Tag-triggered `.woodpecker/release.yml` independently validates the tagged
|
|
source, builds the same three targets, and publishes these Gitea downloads:
|
|
|
|
- `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 tag version and checks host `version` output. CI
|
|
generates checksums and uses non-overwriting publication settings. It does
|
|
not select versions, change the source, or move tags. No image or package
|
|
registry output is declared. Tag publication is not proof that these
|
|
asynchronous downloads are available.
|
|
|
|
## Failure and recovery
|
|
|
|
If validation fails before tagging, correct and commit the candidate, push
|
|
it to `main`, and rerun the publication command. If the tag push reports
|
|
failure, its outcome may be ambiguous: keep the local tag and inspect the
|
|
exact `refs/tags/vMAJOR.MINOR.PATCH` at `origin` before declaring success
|
|
or retrying. A reachable matching remote tag at the recorded commit establishes
|
|
publication; a confirmed absent tag permits investigation of the transport
|
|
failure. If `origin` cannot be inspected, publication status is unknown.
|
|
Do not move, overwrite, or automatically retry the tag. Remove a local tag
|
|
only after confirming it was never published or used by a release channel.
|
|
|
|
A transient CI or delivery failure can be retried from the same immutable
|
|
tag. Missing assets may be added later if they match the tagged source and
|
|
any published checksum manifest; do not overwrite existing binaries,
|
|
checksums, or release-note contents. A source/content defect, or delivery
|
|
that cannot be corrected without replacement, requires a new suitable
|
|
version and matching note. Leave the original release intact.
|
|
|
|
Optional consumer inspection may compare the tag's remote commit with the
|
|
recorded candidate, check the Woodpecker delivery job and hosted Gitea note,
|
|
download the assets into an empty directory, run `sha256sum --check
|
|
SHA256SUMS` (or `shasum -a 256 --check SHA256SUMS` on macOS), and run
|
|
the matching host binary's `version` command. This is separate delivery
|
|
observation, never a source-release gate.
|