Skip to content

Releases

SAE Books follows semantic versioning with a calendar-suffix for preview builds.

1.2.3        # stable
1.2.3-rc.1   # release candidate
2026.04+a3f  # preview (CalVer + commit)

Branches

  • main — always green, deployable HEAD
  • feature/<slug> — short-lived feature branches
  • release/<version> — cut from main for release stabilisation

Cutting a release

  1. Branch release/1.2 from main
  2. Bump pyproject.toml to 1.2.0-rc.1, tag, push
  3. Run the full test suite + integration smoke
  4. Tag 1.2.0 once green; build and push images
  5. Merge release/1.2 back to main (fast-forward only)

Image tagging

The CI workflow (build-images.yml) builds multi-arch images (linux/amd64, linux/arm64) on every push to main and on version tags. The image name is saebooks-api; registry push configuration is pending a registry URL decision. Expected tag convention once configured:

saebooks-api:1.2.3
saebooks-api:1.2
saebooks-api:latest

Changelog

Release notes are hand-curated, grouped by version with sub-sections ### Added, ### Changed, ### Fixed, ### Removed. There is no CHANGELOG.md in the repository yet — this convention applies from the first public release.

Database migrations across releases

Aim for one migration step per release. If you accumulate many schema changes during a development cycle, squash them into a single migration before tagging — easier to reason about for downstream operators applying the upgrade.

A migration that drops a column or table needs a deprecation cycle: land the column-unused change in release N, then the drop in N+1 (or later). Never drop in the same release that stops writing.