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

  1. Sign in to crates.io with the account that will own kotlin-codegen. Verify the account email if crates.io requests it.
  2. 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.
  3. In GitHub → kotlin-codegen → Settings → Environments, create an environment named crates-io.
  4. Add the API token to that environment as a secret named CARGO_REGISTRY_TOKEN. Do not set the CRATES_IO_TRUSTED_PUBLISHING variable yet.
  5. Optionally add a required reviewer to the environment so publication needs explicit approval.

Prepare and publish 0.1.0

  1. Confirm that Cargo.toml contains version 0.1.0 and that CHANGELOG.md contains a ## 0.1.0 section.

  2. 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
    
  3. Merge the release-preparation PR into main only after CI passes.

  4. Optionally rehearse first: open Actions → Publish to crates.io → Run workflow, select main, enter 0.1.0, and enable dry_run. This runs every check and cargo publish --dry-run without publishing or tagging.

  5. Open Actions → Publish to crates.io → Run workflow.

  6. Select main, enter 0.1.0 without a v prefix, leave dry_run unchecked, and run the workflow.

  7. Approve the crates-io environment deployment if approval is required.

  8. Confirm that the workflow created all three release artifacts:

    • kotlin-codegen 0.1.0 on crates.io;
    • tag v0.1.0 pointing 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:

  1. Open the kotlin-codegen crate's Settings → Trusted Publishing page.

  2. Add a GitHub Actions publisher with these exact values:

    • repository owner: milyin
    • repository: kotlin-codegen
    • workflow: publish.yml
    • environment: crates-io
  3. In the GitHub crates-io environment, add the variable CRATES_IO_TRUSTED_PUBLISHING with the value true.

  4. Delete the CARGO_REGISTRY_TOKEN secret from the environment.

  5. 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

  1. In a release-preparation PR:

    • update the version in Cargo.toml;
    • add the matching ## <version> section to CHANGELOG.md;
    • update the README and API documentation as needed;
    • run the local release checks shown above.
  2. Merge the PR into main after CI passes.

  3. Run Actions → Publish to crates.io from main with the exact manifest version, without the v prefix. Enable dry_run first if you want a rehearsal.

  4. 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.