Skip to content

Runbook: Releases

How we version the site and publish release notes. The site deploys continuously from main (deploy runbook) — a release is a communication checkpoint, not a deployment event: a Git tag plus a GitHub Release whose notes tell the story of what shipped since the last one. Releases never gate deploys, and deploys never wait for releases.

  • Versions are narrative, not a compatibility contract. Nothing depends on this repo’s version number, so it exists to communicate. House meanings:
    • Major — redesign / rebrand / platform-migration scale; the kind of change that gets its own ADR. Rare and deliberate (! / breaking).
    • Minor — a new user-visible capability: a section, the docs site, search, a careers system (feat).
    • Patch — everything else: fixes, perf, content, dependencies.
  • Cadence: release when there’s a story — when the accumulated notes read as a coherent “what’s new” (in practice every 2–6 weeks). Don’t cut releases for dependency-only stretches, and don’t let the draft go stale for more than a quarter.
  • Every release opens with a human lede — one to three sentences of narrative before the generated list. The mechanics are automated; the story is not.

Release Drafter (.github/workflows/release-drafter.yml, config in .github/release-drafter.yml) maintains a rolling draft GitHub Release:

  • Every merge to main updates the draft. Merged PRs are grouped into categories (Features / Fixes / Performance / Docs / Maintenance) by a label, and the label is applied automatically from each PR’s Conventional title by label-conventional.yml (feat → Features, fix → Fixes, …; ! adds breaking). The next version is resolved from those same labels (a suggestion — you confirm it at publish).
  • The draft is visible only to maintainers (Releases → the draft at the top). No release PR exists, nothing is tagged, and CI is uninvolved — the draft is pure metadata accumulation, push-triggered only.
  1. Open the draft under Releases and read it: does it tell a story? If not, wait.
  2. Confirm the version per the house meanings above (the draft resolves one from the labels; adjust if judgment says otherwise).
  3. Replace the lede placeholder with 1–3 sentences of narrative.
  4. Publish. GitHub creates the vX.Y.Z tag on current main and the Release goes live. That’s the entire ceremony.
  • Keep PR titles Conventional (feat(...), fix(...), …) — they drive the category label, the release-note line, and the version signal (see CONTRIBUTING.md). A PR labeled skip-changelog is excluded from the notes.
  • The first public release (v1.0.0) was created manually at the repo’s birth with hand-written notes; Release Drafter handles everything after it.
  • There is no CHANGELOG.md file — the Releases page is the changelog.