Releasing¶
How a Folia release is cut. The tag and the GitHub release are made by hand by the project owner,
from a commit of main that passed its checks; the Linux binary is built by the
release workflow. Nothing here publishes to crates.io (publish = false).
Checklist¶
Everything on main, CI green:
- Pull requests: the ones the release needs are merged, and
git statusis clean onmain. - Version: the workspace
versioninCargo.tomlis the release's,Cargo.lockfollows,folia --versionprints it, and the example's feedsgeneratormatches (a test checks it). - Release notes:
docs/release-notes/vX.Y.Z.mdandCHANGELOG.mdare current, and say what the release is not (it does not claim the Jekyll site is replaced). - Checks:
just checkandjust check-paritypass, CI on the commit is green, andcargo deny checkis clean. - Clean clone: in a fresh clone of that commit,
just check,just check-parity,just build-example DIRandjust serve DIRwork (the manual testing guide; for a clean machine, its install commands). - Real site (if you have its private inputs):
just pages <label>andjust determinismon that commit say what you expect; the classified verdicts (clean build, exact parity) go in the release's private evidence, never in this repository.
Then, from the commit you checked, the owner tags it and pushes the tag:
git tag -s -a vX.Y.Z -m "Folia X.Y.Z" # signed, after the checklist
git push origin vX.Y.Z
The tag starts the release workflow (below), which builds the binary and leaves a draft release
with it attached. Read the draft, check that its text is docs/release-notes/vX.Y.Z.md, and
publish it (mark it a pre-release while the version is 0.x). The links in the notes are relative
(they work in the docs site); the workflow rewrites them to the tag's files on GitHub.
The release workflow¶
.github/workflows/release.yml builds folia for Linux x86_64 (glibc 2.35, Ubuntu 22.04) with
cargo build --release --locked, with no dependency cache. It then:
- refuses a tag that is not
vX.Y.Zor does not equal the workspace version; - checks the binary (
folia --versionis the version; it builds the example site); - packs
folia-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz(the binary,LICENSE,DISCLAIMER.md) with a.sha256file, and attests the tarball's build provenance (GitHub artifact attestation); - on a pushed tag, attaches both to the release: a new draft from the notes file if the tag has no release, else the existing one, whose text it never changes.
Run by hand (Actions, "Release", with the tag) it builds an existing tag; ticking publish attaches
the files to that tag's release. That is how a release made before the workflow got its binary.
Verify a download:
sha256sum -c folia-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz.sha256
gh attestation verify folia-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz --repo ggirelli/folia-web
The workflow's permissions are the least that work (contents: write only in the job that
attaches files); its actions are pinned by commit. It builds nothing from a site's private inputs,
and never publishes by itself. macOS is not built: its CI job is informational and has not been
green for long. Windows is not supported.