3.6 KiB
Releasing Narratio
This document is the maintainer procedure for creating a Narratio source and
binary release. The synchronous release boundary is a successful push of one
new tag to origin; Woodpecker and Gitea publication happen later and do not
change that result.
Choose a version and write its note
Narratio is past v1.0.0. Use an unused stable tag in the exact form
vMAJOR.MINOR.PATCH:
- increment
MINORfor backward-compatible features; - increment
PATCHfor backward-compatible fixes; and - reserve a new
MAJORfor an intentional breaking documented contract.
Before preparing the candidate, create
docs/releases/vMAJOR.MINOR.PATCH.md with this structure:
# Narratio vMAJOR.MINOR.PATCH
This release ...
## Summary
## Compatibility
## Upgrade
## Changes
The compatibility section identifies relevant CLI, configuration, artifact, integration, or operating-contract changes. The upgrade section states the required operator action, or explicitly says that no special action is required. Release notes are immutable historical summaries; link to the current canonical documentation for detailed behavior.
Commit the note and all candidate changes, then use the ordinary development
workflow to push that commit to main. Do not create a release tag before the
candidate is committed and origin/main contains the exact same commit.
Validate the candidate
Run the shared checker from any directory:
scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH
It validates the version and matching note, module hygiene, formatting,
whitespace, uncached tests, race tests, static checks, documentation, examples,
and six official 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 any failure on main, commit it, push it normally, and rerun the
checker.
The checker builds Linux, macOS, and Windows assets for amd64 and arm64.
Cross-builds prove compilation; they are not native macOS or Windows runtime
evidence.
Publish the tag
From a clean checkout on main whose HEAD equals origin/main, run:
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 pushes only:
refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH
It never commits changes, pushes main, force-pushes, moves a tag, or pushes
all tags. A successful push of that exact ref completes the release command;
the command prints the tag and commit, then returns without waiting for CI,
querying Gitea, downloading assets, or checking checksums.
If a failure occurs before the tag is created, correct the candidate on main
and repeat validation. If the push fails after local tag creation, the local tag
is intentionally retained for inspection and the command must not be retried
blindly. Once the upstream tag has been pushed, it is immutable. Correct any
defect or failed asynchronous publication with a new patch version, a new
release note, and the complete procedure again.
Optional asynchronous inspection
After a successful tag push, a human may later inspect the tag-triggered Woodpecker run and the corresponding Gitea release for binaries and checksums. This is optional follow-up only. Automated releasers must not wait for, poll, or treat CI/Gitea completion as a condition of the successful tag push.