Skip to content

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

@aviator5

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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions