Every release uses ./scripts/release.sh. Do not bump versions, tag, or create GitHub Releases manually.
- Install GitHub CLI (
gh) and authenticate. - Install
cargo-edit(cargo install cargo-edit) socargo set-versionis available. - Configure the
CRATES_IO_TOKENsecret in thecrates-ioGitHub environment thatpublish.ymluses.
-
Add user-facing notes under
## [Unreleased]inCHANGELOG.md. -
Prepare the release PR:
./scripts/release.sh prepare patch # or minor | major | 1.2.3 -
Merge the PR after CI passes (including the changelog check).
-
Publish from a clean default branch checkout:
git checkout main git pull ./scripts/release.sh publish
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 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.
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.