Skip to content

Migrate crates.io release pipeline to release-plz #96

Description

@aviator5

Summary

Migrate the crates.io release pipeline from the hand-rolled publish-crates
job in .github/workflows/release.yml to release-plz.

Motivation

The current release workflow hand-rolls workspace publishing in bash, and that
hand-rolled logic has produced two distinct release-blocking bugs:

  1. Per-crate dry-run cannot resolve internal deps. The preflight ran
    cargo publish -p <crate> --dry-run per crate. On a version bump, a dependent
    crate (e.g. gts-macros -> gts-id ^0.10.0) fails because the new version is
    not yet on crates.io. Fixed by switching to cargo publish --workspace --dry-run
    (which resolves internal deps against the locally packaged crates).

  2. crates.io API polled without a User-Agent. is_published() / wait_visible()
    call the crates.io API with curl but no UA header. crates.io's data-access
    policy rejects such requests with HTTP 403, so is_published always returns
    false and wait_visible spins for 5 minutes then errors out — even though the
    crate was actually published. Fixed by sending a descriptive UA header.

Both are symptoms of the same root problem: we are re-implementing publish
ordering, registry-index propagation waiting, and API access ourselves, instead
of delegating to a mature tool. Each release exercises fragile code paths that
only break on real version bumps, which is exactly when they are hardest to test.

Proposal

Adopt release-plz, as already done in the sibling Cyber Fabric (cyberware-rust)
repository. release-plz handles:

  • topological publish ordering across interdependent workspace crates;
  • registry-index propagation waiting + throttling (publish_timeout);
  • crates.io API access with a correct client;
  • changelog generation from Conventional Commits (already followed here);
  • version bumping via a "release PR" flow;
  • GitHub release creation.

Reference implementation: cyberware-rust.github/workflows/release-plz.yml
and release-plz.toml.

Open questions / decisions

  • Cross-platform binaries. The current release.yml also builds gts binaries
    for linux x64/arm64, macOS arm64, and windows, and uploads them to the GitHub
    Release with SHA256SUMS. release-plz does not build binaries. Decide between:
    (a) keep a separate binary-build job triggered off the release-plz tag/release;
    (b) drop prebuilt binaries (rely on cargo install);
    (c) keep the current tag-driven workflow for binaries + GH release and use
    release-plz only for crates.io publishing.
  • Release model. Move from the current tag-driven manual version bump to the
    release-plz release-PR flow, or keep manual control?
  • publish = false crates. gts-cli and gts-macros-cli must remain unpublished
    (already publish = false in their manifests; mirror in release-plz.toml).
  • Repository guard. Gate the publish job on github.repository == 'GlobalTypeSystem/gts-rust'
    so forks (e.g. aviator5/gts-rust) never publish.

Out of scope / follow-up

The two bugs above are already fixed in release.yml as a stopgap so that the
in-flight v0.10.0 release can complete. This issue tracks the proper migration
that removes the hand-rolled logic entirely.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions