Skip to content

Publish to crates.io when the version changes - #13

Merged
pathscale merged 1 commit into
masterfrom
ci/publish-on-version-change
Jul 29, 2026
Merged

Publish to crates.io when the version changes#13
pathscale merged 1 commit into
masterfrom
ci/publish-on-version-change

Conversation

@pathscale

Copy link
Copy Markdown
Owner

Answers "did you wire up auto push to crates on version change?" — no, and now yes.

Merging a Cargo.toml version bump to master publishes that version and tags the commit.

Designed around publishing being irreversible

A published version can never be unpublished or reused, so every choice here favours doing nothing over doing something twice:

  • The registry decides whether work is needed, not a diff against the previous commit. A rerun, a revert or a manual publish all leave the diff misleading and the registry correct. An accidental rerun is a no-op, not a failure.
  • Only Cargo.toml triggers it, since only Cargo.toml carries the version. An ordinary merge publishes nothing.
  • A concurrency group serialises it, so two merges in quick succession cannot race into the registry.
  • The full check suite runs inside the publish job, rather than trusting the CI workflow to have finished. Both fire on the same push and nothing orders them.
  • The tag is pushed after a successful publish, so it never points at a version that failed to go out.
  • A missing token fails with its name and where to add it, rather than as an opaque auth error from cargo half way through a release.

The token is read through the environment rather than interpolated into a command, so it cannot reach a shell trace.

Verified before pushing

Both branches of the version check were run locally against the real registry:

extracted: 0.2.1
on crates.io: 0.2.0 0.1.0
RESULT: not published -> would publish 0.2.1
RESULT for 0.2.0: correctly detected as published -> would skip

One thing you have to do

The repository has no secrets configured. I checked, and I am deliberately not handling the token value.

Create one at https://crates.io/settings/tokens with publish-update scope, then add it as CARGO_REGISTRY_TOKEN under Settings → Secrets and variables → Actions.

Until then the job fails loudly with that instruction rather than silently skipping.

What happens when this merges

Master is already at 0.2.1, which is not published. So merging this PR touches Cargo.toml... actually it does not — this PR only adds a workflow file. The trigger is paths: ["Cargo.toml"], so merging it publishes nothing.

To release 0.2.1 once the secret exists, run the workflow manually (workflow_dispatch is enabled for exactly this), or let the next version bump carry it. I would suggest the manual run, so the first execution is watched rather than incidental.

Releases were manual: bump, merge, then remember to run cargo publish from a
clean checkout. The remembering is the part that fails.

Merging a Cargo.toml version bump to master now publishes that version and tags
the commit. Built around the fact that a publish cannot be undone and a version
number can never be reused:

- The registry, not a diff, decides whether work is needed. A rerun, a revert or
  a manual publish all leave a diff misleading and the registry correct, so an
  accidental rerun is a no-op rather than a failure.
- Only Cargo.toml triggers it, since only Cargo.toml carries the version, so an
  ordinary merge publishes nothing.
- A concurrency group serializes it, so two merges in quick succession cannot
  race each other into the registry.
- The full check suite runs inside the publish job rather than trusting the CI
  workflow to have finished. Both fire on the same push and nothing orders them.
- The tag is pushed after a successful publish, so it never points at a version
  that failed to go out.
- A missing token fails with its name and where to add it, rather than as an
  authentication error from cargo part way through a release.

The token is read through the environment rather than interpolated into a
command, so it cannot reach a shell trace.

Both branches of the version check were run locally against the real registry
before this was committed: 0.2.1 correctly reads as needing publication and
0.2.0 as already done.
@pathscale
pathscale merged commit ad8ee56 into master Jul 29, 2026
2 checks passed
@pathscale
pathscale deleted the ci/publish-on-version-change branch July 29, 2026 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant