Versioning & Cutting a Release
Versioning is driven by a single /VERSION file at the repo root, and releasing is (deliberately) almost entirely automatic — the discipline is in the bump, not in manual release steps. (For the full scheme, semver rules, and the version-check enforcement, 015_VERSIONING.md is authoritative; this is the operational view.)
The scheme
Semantic versioning from the VERSION file:
0.x.0— bump the minor after each feature/spec implementation;0.x.y— bump the patch for bug fixes;1.0.0— production-ready.
Image tags
The tag a build produces depends on the trigger:
| Trigger | Tags | For |
|---|---|---|
merge to staging | staging-sha-…, staging-latest | the staging environment |
GitHub Release (from main) | v0.18.0, sha-…, latest | production |
The bump process
On your feature branch, before merging:
./scripts/bump-version.sh 0.18.0— bump theVERSIONfile.- Update
CHANGELOG.md. - Create
.release_notes/0.18.0.md— a human-facing summary. - Merge to
staging(staging deploys automatically). - Merge
staging→main— the release workflow builds versioned images, deploys to production, and creates the GitHub Release automatically.
Releases are opt-in by release-notes file
Here's the elegant part: a GitHub Release is created only if a new .release_notes/{VERSION}.md exists. That makes releasing opt-in — the same merge that deploys will cut a release when (and only when) you've written the notes, with no manual release step after merge. And the production PR's version-check enforces the discipline, so a version bump without its release notes (or vice versa) is caught before merge rather than producing a half-made release.