Files
narratio/docs/release.md

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 MINOR for backward-compatible features;
  • increment PATCH for backward-compatible fixes; and
  • reserve a new MAJOR for 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.