- states plainly what does NOT trigger it: builds run on a
GitHub-hosted runner, not locally, and only on a `v*` tag push —
pushing master releases nothing
- 14 numbered steps: get the workflow onto GitHub, enable Actions,
allow ocaml/setup-ocaml, the 403/workflow-permissions fallback,
a --draft rehearsal on a throwaway tag, cleanup, then the real tag
- calls out that the rehearsal tag is EXPECTED to fail the tag/VERSION
guard, and how to rehearse the full job instead
- step 8/9: read the runner's glibc floor and reconcile
install/view.wo with it — the runner, not the dev machine, decides
who can run the release
- lists the three likely first-run failures
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- .github/workflows/release.yml: builds, verifies and publishes on a
`v*` tag. `permissions: contents: write` on the injected
GITHUB_TOKEN replaces `gh auth login`; no PAT, nothing to rotate
- runs-on ubuntu-22.04 DELIBERATELY: the build host's glibc caps which
symbol versions the binaries import, and that cap is the floor every
user needs. 22.04 (2.35) includes Ubuntu 22.04 / Debian 12 / RHEL 9;
24.04 (2.39) would exclude them
- guards that fail instead of publishing: tag vs VERSION, produced
asset name vs the filename /install links, sha256, and a smoke test
that builds a hello project with the binaries INSIDE the tarball
- reports the shipped glibc floor so the claim on /install is checkable
from a build log
- releasing.md: pipeline route up front, manual route kept; GH_TOKEN
recipe for non-GitHub CI
Not run — this repo has no CI history and Actions cannot execute
locally. Every guard's shell was dry-run here against the real dist.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- gh's credential is separate from git's: SSH keys let you push but
not call the API, so a machine that pushes can still fail to release
- the five interactive prompts and what to answer, with SSH as the
protocol to match this repo's existing remote
- headless path: PAT scopes (classic repo/read:org/gist, fine-grained
Contents: read and write), --with-token from a 600 file, GH_TOKEN
for automation
- verify with `gh repo view shoneyJ/writeonce` — proves the token
reaches THIS repo, not just that it is valid
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- docs/guides/releasing.md: the steps from `just dist` to a working
download button
- pins the constraint that matters: the asset filename and tag must
match the URL /install links, or the button 404s
- includes verifying the tarball with the binaries INSIDE it, tagging
the built commit, `gh release create` with both files, the web-UI
path, and a curl check of the exact link the site uses
- notes dist/ is gitignored, the shoneyJ/shoneyj path-case difference,
and what a version bump must touch in install/view.wo
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>