6.6 KiB
Release Procedure
The release policy owns versioning, compatibility,
publication completion, and immutability. This runbook supplies Scriptorium's
commands; release notes under docs/releases/ are historical summaries.
Prepare The Candidate
Use a POSIX shell, Git with a configured tagger identity and access to
origin, and a Go toolchain compatible with go.mod. The native host must
support Go's race detector and have its required C compiler. If Git is
configured to sign tags, its signing tool and key must be available. Run from the
repository root. Provision the toolchain and module cache before offline
validation; when dependencies are not cached:
GOWORK=off go mod download
Choose an unused stable version under the release policy. Commit its note as
docs/releases/<version>.md, beginning with a title such as
# Scriptorium v0.14.0 (an example, not an instruction to select that version).
Include a concise summary and relevant compatibility impact or upgrade action.
End the note with the following footer, replacing <version> in both absolute
URLs with the selected version tag (for example, v0.14.0):
[LICENSE](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/<version>/LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/<version>/docs/oss/attribution.md)
Check that both URLs name files in the candidate tree at that tag. The tag may not resolve online until publication. The checked-in note is copied unchanged into the hosted release body by the existing workflow, so do not maintain a second footer there. Update affected canonical documentation with the change, and retire completed roadmap material when appropriate while preserving deferred work and links. No extra release-specific review signoff is required.
Finish and commit the intended candidate on main, then publish that branch:
git -c push.followTags=false push origin refs/heads/main:refs/heads/main
The publication command inspects the configured push endpoint of origin,
not a potentially stale remote-tracking ref. If a separate push URL is
configured, it is authoritative for both checks and publication. Configure one
publication URL; multiple push endpoints cannot be validated as one remote.
Publish
Invoke the single publication command, substituting the selected version:
sh scripts/release.sh v0.14.0
The command validates a clean worktree and index on main, an unused local and
remote version, exact agreement with authoritative remote main, and a
checked-in note whose first-level title contains Scriptorium and the exact
version. Ignored local files do not make the candidate dirty.
The existing source-boundary guards reject committed workspaces, vendor trees, and module replacements. No migration-specific exact Promptkit version audit is required.
It then runs the complete suite once with the race detector and builds Linux
amd64 and arm64 binaries using CGO_ENABLED=0, -trimpath, and
-ldflags '-s -w'. The native test run uses the host platform and enables cgo.
Validation disables workspaces, uses read-only module mode, and disables module
and toolchain downloads. Missing dependencies must be provisioned separately;
fix the environment and rerun the command. No persistent validation cache is
maintained by the release tool.
The command rechecks candidate and publication state, creates an annotated tag from the committed note, and pushes only that tag's exact object to its explicit ref. It does not push branches, follow other tags, force updates, or wait for CI. Temporary notes and validation builds are removed on exit. The successful summary identifies the source commit and tag object and reports binary delivery separately as asynchronous and unverified.
Asynchronous Binary Delivery
The tag-triggered hosted workflow builds and publishes:
scriptorium-<version>-linux-amd64;scriptorium-<version>-linux-arm64; andSHA256SUMS.
The matching checked-in note supplies the hosted release body. The workflow owns image selection, packaging, checksum generation, and upload configuration. Its upload step skips existing files and does not overwrite the release. Source-publication success does not attest to workflow success or asset availability.
Workflow inspection, downloads, checksum verification, and a compatible-host smoke test are optional delivery diagnostics. They must not delay or redefine source-release completion. No polling or consumer-installation check is part of the publication command.
Failure Recovery
Before tag creation, correct and commit a failed candidate, publish main,
and invoke the publication command again. A changed candidate must pass its
own validation.
After an unsuccessful push, the command queries the authoritative endpoint. If it confirms the exact tag object and candidate, it reports source success. Otherwise it exits unsuccessfully and preserves the local tag. It never retries a push or deletes a tag automatically. If the endpoint is unavailable, the publication status is unknown, not evidence that nothing was published.
For manual diagnosis, select the affected version and compare the local tag object and peeled commit with the authoritative remote:
release_version=v0.14.0
release_remote=$(git remote get-url --push origin)
git rev-parse "refs/tags/$release_version" "refs/tags/$release_version^{commit}"
git ls-remote "$release_remote" refs/heads/main \
"refs/tags/$release_version" "refs/tags/$release_version^{}"
Do not retry while the outcome remains unknown. If the tag exists remotely, do not move, recreate, or delete it. If the tag was never published or used by any release channel, an explicitly authorized local cleanup may delete only that unpublished tag; then rerun the command to validate and publish the candidate. The command intentionally rejects an existing local tag rather than assuming that a previous process validated it.
For transient delivery failures, inspect what has already been uploaded before retrying the same immutable tag. The upload step's skip behavior alone does not prove checksum consistency. Add missing assets only if they match the tagged source and any already-published manifest, without replacing existing contents. Compare rebuilt bytes with published checksums when recovering a partial upload; do not assume toolchain changes reproduce identical binaries. If safe completion is impossible, or published source, notes, packaging, or artifact contents need correction, leave the original release intact and publish a new version from a corrected commit.