Releasing
August 6, 2026 · View on GitHub
Releases are published from GitHub Actions
(.github/workflows/publish.yml). The workflow
runs every release check, uploads the crate, verifies the archive served by
crates.io, and only then creates the matching vX.Y.Z tag and GitHub release.
Do not run cargo publish or create the tag locally.
kotlin-codegen is a zero-dependency library, so its Cargo.lock is not
committed and the release checks intentionally do not use --locked.
kotlin-codegen must be published before prebindgen-jni, which depends on it.
First publication: 0.1.0
Trusted Publishing cannot create a crate that does not exist on crates.io yet. The first publication therefore uses a scoped crates.io API token while still running the complete release from CI.
Configure crates.io and GitHub
- Sign in to crates.io with the account that will own
kotlin-codegen. Verify the account email if crates.io requests it. - Create a crates.io API token that is allowed to publish a new crate. Give it a short expiration because it is needed only for the first release.
- In GitHub → kotlin-codegen → Settings → Environments, create an
environment named
crates-io. - Add the API token to that environment as a secret named
CARGO_REGISTRY_TOKEN. Do not set theCRATES_IO_TRUSTED_PUBLISHINGvariable yet. - Optionally add a required reviewer to the environment so publication needs explicit approval.
Prepare and publish 0.1.0
-
Confirm that
Cargo.tomlcontains version0.1.0and thatCHANGELOG.mdcontains a## 0.1.0section. -
Run the release checks locally:
cargo fmt --all -- --check \ --config "unstable_features=true,imports_granularity=Crate,group_imports=StdExternalCrate" cargo clippy --all-targets --all-features -- -D warnings RUSTDOCFLAGS="-D warnings" cargo doc --no-deps cargo test --all-targets --all-features cargo package -
Merge the release-preparation PR into
mainonly after CI passes. -
Optionally rehearse first: open Actions → Publish to crates.io → Run workflow, select
main, enter0.1.0, and enable dry_run. This runs every check andcargo publish --dry-runwithout publishing or tagging. -
Open Actions → Publish to crates.io → Run workflow.
-
Select
main, enter0.1.0without avprefix, leave dry_run unchecked, and run the workflow. -
Approve the
crates-ioenvironment deployment if approval is required. -
Confirm that the workflow created all three release artifacts:
kotlin-codegen0.1.0 on crates.io;- tag
v0.1.0pointing to the published commit; - GitHub release
v0.1.0.
The workflow verifies that the downloaded crates.io archive records the same
Git commit before it creates the tag. If publication succeeds but a later step
fails, rerun the workflow with 0.1.0; it resumes without uploading the version
again.
Switch to Trusted Publishing after 0.1.0
Once 0.1.0 exists on crates.io:
-
Open the
kotlin-codegencrate's Settings → Trusted Publishing page. -
Add a GitHub Actions publisher with these exact values:
- repository owner:
milyin - repository:
kotlin-codegen - workflow:
publish.yml - environment:
crates-io
- repository owner:
-
In the GitHub
crates-ioenvironment, add the variableCRATES_IO_TRUSTED_PUBLISHINGwith the valuetrue. -
Delete the
CARGO_REGISTRY_TOKENsecret from the environment. -
After one later release succeeds through Trusted Publishing, optionally enable Trusted-Publishing-Only mode in the crate settings.
Later publication jobs exchange GitHub's OIDC identity for a short-lived crates.io token. No permanent crates.io credential remains in GitHub.
Publish a later version
-
In a release-preparation PR:
- update the version in
Cargo.toml; - add the matching
## <version>section toCHANGELOG.md; - update the README and API documentation as needed;
- run the local release checks shown above.
- update the version in
-
Merge the PR into
mainafter CI passes. -
Run Actions → Publish to crates.io from
mainwith the exact manifest version, without thevprefix. Enable dry_run first if you want a rehearsal. -
Confirm the crates.io version,
v<version>tag, GitHub release, and docs.rs documentation.
Recover from a partial release
Rerunning the workflow with the same version is safe:
- If crates.io does not contain the version, the workflow publishes it.
- If it is already published from the current commit, publication is skipped and release creation resumes.
- If it was published from another commit, the workflow stops.
- An existing tag is reused only if it points to the published commit.
Published versions cannot be replaced. Correct a bad release by publishing a new version; never move a published version's tag.