It seems my needs should be quite common: I have 2 libraries/crates in a single repository/workspace. CrateA depends on CrateB. In CrateA's Cargo.toml, I have
Code changes are landing in the repository (after going through integration tests, code reviews, etc...), but without publishing anything.
I would like to regularly run an automated "publish" job that would do the following:
if only things in crate_a changed (since last published versions of the crates), bump crate_a version, and publish crate_a
if things changed both in crate_a and crate_b, bump both crates versions, and also the version in crate_a's dependency to crate_b to match, and publish the 2 crates (it doesn't really have to be atomic)
if things changed only in crate_b, and are minor, bump and publish crate_b
if things changed only in crate_b, but are major, bump and publish crate_b, but then also propagate to change/publish crate_a
Basically, just "publish new versions if there is new stuff, but don't publish a new version if nothing changed". And I am treating a major dependency update as a major change.
I'm struggling to find a reasonable way to achieve this. So far, my best solution would be:
run cargo semver-checks once, and parse the output to determine what first wave of version bumps have to happen
run cargo release version <level> -p <crate> to perform these required bumps
implement myself something that propagates major changes (my last case from above)
run cargo release again to perform the publication, tagging, pushing, etc
This is the exact use case cargo workspaces publish was designed for. I already use it in a couple repos at work, as well as for some personal projects.
For the version bumping and changelog side of things I follow a Release Please workflow.
Basically, I took the release workflow from @fasterthanlime's amazing "My Ideal Rust Workflow" article and adapted it for my use case.
If it helps, here is the GitHub Actions workflow I use for releases:
I don't wish to introduce a new drastic syntax and restrictions on commit messages, so it looks like "release please" wouldn't work.
At this point I'd probably be fine with something that just goes: "anything changed in the crate, let's bump the major version".
But also on the "cargo workspaces" side, I'm a bit confused by the "independant" option: I just want to avoid bumping versions "just because the global version changed", but I still want a bump when dependencies got bumped. Even in the simplest crate_a->crate_b case, I'm not sure which should be "independant".
It seems that using these would also mean a lot of glue code and combining 2 different plugins.