Release Checklist
Use this checklist for every release candidate. Local release validation and scheduled CI are useful inputs, but neither substitutes for a successful gated run of the exact commit that will be published.
1. Freeze the candidate
- Finish the version, changelog, migration-note, and release-PR changes.
- Record
git rev-parse HEAD. This is the full 40-character release-candidate SHA. - Run
bun run release:checklocally. If Docker is unavailable, run./tests/release-check.sh --skip-dockerand rely on the gated Docker job below for the container matrix.
Any commit added after this point creates a new candidate and invalidates the gated evidence collected for the previous SHA.
2. Collect exact-SHA gated evidence
GitHub only offers a scheduled or manually dispatched workflow after its file exists on the default branch. When validating the commit that first introduces or changes this workflow, create a unique lightweight candidate tag at the recorded SHA:
candidate_sha="$(git rev-parse HEAD)"
candidate_short_sha="$(git rev-parse --short=12 HEAD)"
candidate_version="$(node -p 'require("./package.json").version')"
candidate_tag="gated-ci/candidate-${candidate_version}-${candidate_short_sha}"
git tag "$candidate_tag" "$candidate_sha"
git push origin "refs/tags/$candidate_tag"
Verify that the tag target is the exact candidate commit recorded in step 1.
The gated-ci/candidate-* trigger runs every gated suite from the workflow in
that tagged commit. The resolver checks that the checkout equals the immutable
event SHA, and the final evidence job records both that SHA and the tag ref.
Never force-move or reuse a candidate tag; a changed commit needs a new tag and
a new run.
After Gated CI exists on the default branch, manual dispatch is an equivalent exact-SHA path. From the repository's Actions page, choose Run workflow and supply:
candidate_sha: the full 40-character SHA recorded above, never a branch or tag name.
Every suite runs; there is no suite selector.
The manual request rejects abbreviated SHAs and checks out that immutable commit for every gate. Wait for all of these stable checks to succeed on either candidate path:
Gated / Semantic SearchGated / Docker InstallGated / Native Scheduler / LinuxGated / Native Scheduler / macOSGated / Native Scheduler / WindowsGated / Release Candidate Evidence
The final evidence job records the requested and resolved SHA, the trigger ref, each suite's result, and a run link in the workflow summary. A weekly run is drift detection, not release evidence, because it may cover a different commit.
Manual and tagged candidate runs are cache restore-only. Only a successful scheduled run of the workflow on the repository's default branch may save the HuggingFace model cache; its key identifies both the embedding model and the source/lock inputs. This prevents candidate-controlled workflow code from publishing cache entries while still avoiding repeated model downloads.
Copy the successful run URL (for example,
https://github.com/itlackey/akm/actions/runs/<run-id>) and the exact candidate
SHA into both the release PR and its milestone/parent tracker. Do not publish
from a candidate whose evidence link names a different SHA, whose final
evidence job is skipped, or whose run was re-run after the candidate changed.
3. Gated CI does not run on pull requests
Gated CI runs on three triggers only: the weekly schedule, an exact-SHA
workflow_dispatch, and a gated-ci/candidate-* tag. All three run every
suite.
There used to be a Gated / Detect Changed Paths job that also ran these on
PRs, selecting suites by regex-matching the diff against path lists. It was
deleted in 0.9.8: the patterns had gone stale — they still named test files a
reorganisation had moved or deleted, so it was silently under-selecting suites
and nobody noticed. A build-policing job that quietly stops policing is worse
than no job, because its green status is read as coverage.
Nothing about release evidence changes. Step 2 was always the requirement, and it never went through the PR path.
The candidate-tag trigger is reserved for release evidence and workflow
rollout: it always runs all, because a tag-push workflow is the path available
before the workflow file reaches the default branch.
4. Publish
After the exact-SHA gated run and local release check are green, trigger the
Release workflow with the version already committed in package.json. Keep the
candidate SHA and Gated CI run URL in the release record so the published
artifact's validation can be audited later.