A release is one tag push. Everything else is automated, with a few manual follow-ups for registries that need a pull request.
Repository secrets:
| Secret | Used by |
|---|---|
CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID |
deploy-ui.yml, Pages project buildprof |
HOMEBREW_TAP_TOKEN |
release.yml, pushes the formula to LalitMaganti/homebrew-tap |
CARGO_REGISTRY_TOKEN |
deploy-ui.yml, cargo publish after the UI is live |
Also create the empty homebrew-tap repository.
- Move the
Unreleasedsection ofCHANGELOG.mdunder the new version and date, and setversioninCargo.toml. The crate version names the UI's/v<version>/directory and is what the CLI opens, so they must match. Re-recordexamples/*.buildprofwith this version if the trace format changed (seeexamples/README.md). - Run
just release-prepare, which readsCargo.tomland updates the action's default recorder version, the docs' release-tag example, and the earlier release CI installs. Runcargo checkto refreshCargo.lock. Then runjust release-check, commit, push, and wait for CI. - Tag and push:
git tag v0.2.2 && git push origin v0.2.2. - Review the draft release
Buildprof <version>that appears on GitHub, edit the notes as needed, and publish it.
Then, in order:
release.yml(dist) builds glibc 2.28, musl, and macOS binaries, the shell installer, checksums, and the Homebrew formula, and creates the GitHub release as a draft. The Homebrew formula points at the release's assets, sobrew installworks once the release is published.- Publishing the release by hand is what fires the next two workflows; a release published by automation would not, which is why the draft step is not optional.
https://buildprof.lalitm.com/install.shis a redirect to the latest release's installer, written byassemble-site, so it needs no update.deploy-ui.ymlbuilds this release's UI, attachesbuildprof-ui-v<version>.tar.zstto the release, assembles the site from every released UI plusexamples/*.buildprof, deploys it, and only then publishes the crate to crates.io.packages.ymlattaches.deband.rpmpackages built from the release tarballs.
Manual follow-ups:
- First release only: submit
packaging/aquaandpackaging/misesomise use -g buildprofresolves without thegithub:prefix. Both track GitHub releases automatically afterwards. - Later, when there is demand: AUR (
packaging/aur/update <version>, then push to abuildprof-binpackage) and nixpkgs (packaging/nix). Neither is part of the initial release.
The action ships under the crate's vX.Y.Z tags. just release-prepare
updates its recorder default, the docs example, and the earlier release CI
installs, all from Cargo.toml; CI and release checks catch drift. Keep
release tags fixed. Consumers can use tags or release SHAs with Dependabot for
upgrade PRs.
Before the first action release, CI permits the labeled v0.2.5 preview;
release checks reject it. Remove the preview exception in
infra/prepare-action-release after that release.
The release being prepared has no assets, so the action's own default cannot
be tested before it is published. PR smoke tests record with a recorder built
from the checkout instead, through the action's recorder input, so they
exercise the code being shipped; one further recording installs the previous
release so that path stays covered, and just release-prepare keeps that
version current. After publication, action-release.yml tests the released
action's default recorder on x86_64 and ARM64.
.github/workflows/release.yml is generated by dist, but a few things dist
cannot express are edited in by hand, and allow-dirty = ["ci"] in
dist-workspace.toml stops dist from overwriting them:
- the release metadata check validates the action default, the docs example, and the release CI installs;
- the GitHub release is created as a draft titled
Buildprof <version>; infra/release-notesreplaces the install section of dist's notes with the documented commands; the changelog and the download table stay as dist wrote them.
To upgrade dist: bump cargo-dist-version, run dist generate with
allow-dirty temporarily removed, diff the result against the committed
file, reapply the release metadata check and "Create GitHub Release" step,
and run actionlint on the result. Keep the install commands in
infra/release-notes, the README, and the homepage overlay in step.
- Before 1.0 the CLI and UI are in lockstep at the minor version: the trace
format may change between minor releases and never in a patch release, and
every released UI stays deployed forever under
/v<version>/so any recording still has a UI that reads it. The root serves the newest and links to the matching version when the minor version differs; patch drift is not called out. - From 1.0 the trace format is stable. Every recording must open in every
later UI; a change that would break that needs a
buildprof.trace_formatbump plus a reader for the old format in the UI, never a new UI for old traces.