165 lines
6.1 KiB
Markdown
165 lines
6.1 KiB
Markdown
# Source Releases
|
|
|
|
This procedure is for maintainers publishing Notarius source releases. A
|
|
release is an immutable lightweight `vMAJOR.MINOR.PATCH` tag on `main` together
|
|
with its checked-in `docs/releases/<tag>.md` note. Tag CI validates that source
|
|
candidate after publication; it does not publish or repair a release.
|
|
|
|
Notarius publishes no binaries, archives, checksums, signatures, containers,
|
|
package-manager entries, or Gitea release objects. Windows is not supported.
|
|
Do not create retrospective notes for the pre-procedure `v0.1.0`, `v0.2.0`, or
|
|
`v0.3.0` tags.
|
|
|
|
## Select And Describe The Release
|
|
|
|
Choose an unused stable semantic version in the form `vMAJOR.MINOR.PATCH`.
|
|
Prereleases are not supported. Before `v1.0.0`, a minor release may change a
|
|
documented CLI, configuration, durable artifact, integration, or operating
|
|
contract when its note explains the impact and required operator action. A
|
|
patch release must not intentionally break those documented contracts within
|
|
its minor line.
|
|
|
|
Create the version-matched note as part of the candidate. Every new note uses
|
|
this structure, with concise, truthful content in each section:
|
|
|
|
```markdown
|
|
# Notarius vMAJOR.MINOR.PATCH
|
|
|
|
This release ...
|
|
|
|
## Summary
|
|
|
|
## Compatibility
|
|
|
|
## Upgrade
|
|
|
|
## Changes
|
|
```
|
|
|
|
The note is a historical summary. Link to current canonical documentation for
|
|
exact behavior, and update that documentation in the candidate rather than
|
|
using the note as a substitute.
|
|
|
|
## Prepare The Candidate
|
|
|
|
Set the selected release version and disable Go workspace use for every
|
|
candidate command:
|
|
|
|
```sh
|
|
RELEASE_VERSION=vMAJOR.MINOR.PATCH
|
|
export RELEASE_VERSION GOWORK=off
|
|
```
|
|
|
|
Run the shared source-candidate checks from the repository. They cover module
|
|
hygiene, tests, race tests, vet, builds, formatting, whitespace, maintained
|
|
configuration validation, and the Linux and Darwin command-build matrix:
|
|
|
|
```sh
|
|
./scripts/check-release-source.sh "$RELEASE_VERSION"
|
|
```
|
|
|
|
Before committing, manually follow every changed local Markdown link and
|
|
review the candidate for unintended files, generated output, credentials, or
|
|
other unrelated changes. Commit the release note and all affected current
|
|
documentation, then run the shared checker against that exact candidate. Push
|
|
the candidate commit to `main` only after it succeeds. Record the exact commit
|
|
only after that push:
|
|
|
|
```sh
|
|
RELEASE_COMMIT=$(git rev-parse 'HEAD^{commit}')
|
|
export RELEASE_COMMIT
|
|
```
|
|
|
|
For private-module installation, configure standard `GOPRIVATE` matching this
|
|
module and ordinary Git authentication for the hosting service before running
|
|
the verification below. The exact authentication mechanism belongs to the
|
|
maintainer environment; never record credentials or environment dumps in a
|
|
release note, command history, or repository file.
|
|
|
|
## Guard And Publish The Tag
|
|
|
|
Fetch current remote references, then run this guard without editing the
|
|
candidate. It requires `main`, a clean worktree and index, disabled workspace
|
|
use, a stable release version, the recorded and pushed commit, a matching note,
|
|
and unused local and remote tags:
|
|
|
|
```sh
|
|
git fetch origin main --tags
|
|
|
|
if ! printf '%s\n' "$RELEASE_VERSION" |
|
|
grep -E -x 'v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)' >/dev/null
|
|
then
|
|
printf '%s\n' "invalid release version: $RELEASE_VERSION" >&2
|
|
exit 1
|
|
fi
|
|
test "$GOWORK" = off
|
|
test "$(git branch --show-current)" = main
|
|
test -z "$(git status --porcelain)"
|
|
test "$RELEASE_COMMIT" = "$(git rev-parse 'HEAD^{commit}')"
|
|
test "$RELEASE_COMMIT" = "$(git rev-parse 'origin/main^{commit}')"
|
|
test -s "docs/releases/$RELEASE_VERSION.md"
|
|
grep -F -x "# Notarius $RELEASE_VERSION" "docs/releases/$RELEASE_VERSION.md"
|
|
for heading in '## Summary' '## Compatibility' '## Upgrade' '## Changes'; do
|
|
grep -F -x "$heading" "docs/releases/$RELEASE_VERSION.md"
|
|
done
|
|
if git rev-parse -q --verify "refs/tags/$RELEASE_VERSION" >/dev/null; then
|
|
printf '%s\n' "local tag already exists: $RELEASE_VERSION" >&2
|
|
exit 1
|
|
fi
|
|
if git ls-remote --exit-code --tags origin "refs/tags/$RELEASE_VERSION" >/dev/null 2>&1; then
|
|
printf '%s\n' "remote tag already exists: $RELEASE_VERSION" >&2
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
Create an explicitly lightweight tag against the guarded commit, verify its
|
|
target, and push only that tag ref:
|
|
|
|
```sh
|
|
git -c tag.gpgSign=false tag "$RELEASE_VERSION" "$RELEASE_COMMIT"
|
|
test "$(git cat-file -t "$RELEASE_VERSION")" = commit
|
|
test "$(git rev-parse "$RELEASE_VERSION^{commit}")" = "$RELEASE_COMMIT"
|
|
git push origin "refs/tags/$RELEASE_VERSION:refs/tags/$RELEASE_VERSION"
|
|
```
|
|
|
|
Never use `git push --tags`, move a published tag, or delete a published tag.
|
|
|
|
## Verify The Published Release
|
|
|
|
Confirm that the remote tag still points at the guarded commit and that the
|
|
note is available from the tagged tree:
|
|
|
|
```sh
|
|
REMOTE_TAG_COMMIT=$(git ls-remote origin "refs/tags/$RELEASE_VERSION" | awk '{print $1}')
|
|
test "$REMOTE_TAG_COMMIT" = "$RELEASE_COMMIT"
|
|
git show "$RELEASE_VERSION:docs/releases/$RELEASE_VERSION.md" >/dev/null
|
|
```
|
|
|
|
Verify a fresh source installation and its diagnostic version. The temporary
|
|
directory confines the installed command to this check:
|
|
|
|
```sh
|
|
release_verification_dir=$(mktemp -d)
|
|
trap 'rm -rf "$release_verification_dir"' 0 HUP INT TERM
|
|
mkdir -p "$release_verification_dir/bin"
|
|
GOWORK=off GOBIN="$release_verification_dir/bin" go install \
|
|
"gitea.maximumdirect.net/eric/notarius/cmd/notarius@$RELEASE_VERSION"
|
|
test "$("$release_verification_dir/bin/notarius" --version)" = "notarius $RELEASE_VERSION"
|
|
```
|
|
|
|
An exact fresh checkout and `GOWORK=off go build ./cmd/notarius` is an
|
|
equivalent source verification when local installation policy requires it.
|
|
`notarius --version` is diagnostic only; downstream compatibility remains
|
|
defined by the published receipt and artifact contracts.
|
|
|
|
## Failure And Correction Policy
|
|
|
|
If candidate validation fails before publication, fix the candidate on `main`,
|
|
rerun the shared checker, and repeat the guards. An unpublished local tag may
|
|
be deleted after inspection.
|
|
|
|
If the remote tag or tag CI reveals a defect, leave the published tag intact.
|
|
Fix the defect on `main`, choose a new patch version, write a new matching
|
|
note, and repeat this procedure. Do not weaken tag immutability or add release
|
|
assets as a workaround.
|