Every release uses ./scripts/release.sh. Do not bump versions, tag, or create GitHub Releases manually.
- Install GitHub CLI (
gh) and authenticate. - Configure the
CRATES_IO_TOKENsecret in thecrates-ioGitHub environment thatpublish.ymluses. cut-release.ymlneeds theHOTDATA_AUTOMATION_PRIVATE_KEYsecret (the same GitHub App the regeneration workflow uses). The App token is what lets the release PR get CI checks and the tag trigger publishing: anything opened or pushed withGITHUB_TOKENtriggers no workflows.
-
Make sure
## [Unreleased]inCHANGELOG.mdhas user-facing notes. -
Cut the release from CI:
gh workflow run cut-release.yml -f bump=minor # or patch | major | 1.2.3This runs
./scripts/release.sh prepareon a runner: it bumpsCargo.toml, rolls[Unreleased]into a## [X.Y.Z]section, opens therelease/vX.Y.ZPR, and enables auto-merge on it. -
The PR merges on its own once CI (including the changelog check) and the review gate pass.
-
Merging the PR runs
./scripts/release.sh publishin CI, which tagsmainwithvX.Y.Z. The tag push publishes the crate and creates the GitHub Release.
Pushing a vX.Y.Z tag triggers two workflows:
| Workflow | Purpose |
|---|---|
publish.yml |
cargo publish the crate to crates.io (after a cargo publish --dry-run --all-features check) |
release.yml |
Create the GitHub Release with notes from CHANGELOG.md |
The arrow feature ships as part of the same crate — features are crate metadata, not a separate publish.
If the release PR merged but the Tag release job failed (so no vX.Y.Z tag exists), rerun
the failed job from the Actions tab, or tag from a clean local checkout:
git checkout main
git pull
./scripts/release.sh publishIf the crates.io publish succeeded but the GitHub Release workflow failed, rerun it from main
without retagging:
gh workflow run "GitHub Release" --ref main -f tag=vX.Y.ZThe tag must already exist on the remote. The workflow checks out that tag, extracts the
matching CHANGELOG.md section, and creates or updates the GitHub Release.
- PR check (
check-release.yml): if the[package]version inCargo.tomlchanges,CHANGELOG.mdmust contain a matching## [X.Y.Z]section. - Tag check (
publish.yml): the tag (withoutv) must match the[package]version inCargo.toml. - Publish guard (
release.sh publish): refuses to tag if the changelog section is missing or the tag already exists.
Together, these make it hard to ship a version without changelog notes or a GitHub Release.
The version lives only in Cargo.toml [package].version. release.sh reads it with
cargo metadata --no-deps and bumps it with cargo set-version. There is no committed
Cargo.lock (the crate is a library), so no lockfile step is needed. Because Cargo.toml
is protected from the code generator via .openapi-generator-ignore, the regeneration
workflow owns its own patch bump with cargo set-version --bump patch.