# Releasing
Releases are cut by pushing a semver tag. The
[`release` workflow](.github/workflows/release.yml) does the rest: it verifies
the tag, builds the binaries, publishes a GitHub Release with changelog notes,
publishes the crate to crates.io, and pushes a multi-arch Docker image to GHCR.
## Prerequisites (one-time)
- **`CARGO_REGISTRY_TOKEN`** repository secret — a crates.io API token with
publish rights. Used by the `publish-crate` job.
- The **Docker image** push uses the built-in `GITHUB_TOKEN` (the workflow
grants it `packages: write`), so no extra secret is needed for GHCR.
## Cutting a release
1. Make sure `main` is green and all changes use
[Conventional Commits](https://www.conventionalcommits.org) (this is what
git-cliff turns into the changelog).
2. Bump `version` in `Cargo.toml` and refresh `Cargo.lock` (`cargo update -p sagittarius`),
then commit on a branch and merge via PR.
3. Tag the merge commit and push the tag:
```sh
git tag v0.1.0
git push origin v0.1.0
```
The tag must match the `Cargo.toml` version exactly — the `verify` job fails the
release otherwise. The tag pattern is `v<major>.<minor>.<patch>` with an
optional suffix; a suffixed tag such as `v0.1.0-rc1` is published as a
**pre-release** (and does not move the Docker `latest` tag).
## What the workflow produces
- A **GitHub Release** with notes generated by git-cliff and the Linux
`x86_64` + `aarch64` (gnu) tarballs plus their SHA-256 sums attached.
- The **`sagittarius` crate** on crates.io (`cargo install sagittarius`).
- A multi-arch **container image** at `ghcr.io/lhelge/sagittarius`, tagged with
the version (`X.Y.Z`, `X.Y`) and — for non-pre-release tags — `latest`.
`CHANGELOG.md` is maintained from the commit history by git-cliff
([`cliff.toml`](cliff.toml)); run `git cliff -o CHANGELOG.md` to refresh it
locally, or `git cliff --latest` to preview the next release's notes.