cargo smart-release
Fearlessly release workspace crates and with beautiful semi-handcrafted changelogs.
Key Features
- zero-configuration
cargo smart-release
needs no extra flags to do the right thing™️ smartly. If your intervention is needed it will let you know before it makes changes.- It won't do anything if there are no changes.
- made for multi-crate workspaces
- "Nothing stands by itself, and everything is interconnected" - is how it sees the world, allowing it to efficiently handling complex workspace graphs.
- works just as well for single-crate workspaces
- changelogs-deluxe
- It maintains beautiful changelogs for you while allowing you to edit them for the final polish.
- See your release notes via in-repository tag objects and in GitHub Releases
- plays well with
cargo release
cargo changelog
writes changelogs non-destructively, and only that, leaving the release workflow to cargo-release.
If seeing is believing, here is a 12 minute demonstration, and the same in 30 minutes is also available.
Made for this Workflow
When developing various crates in a workspace, when committing changes and if the edit is breaking, a feature, or another change I want to see in changelogs, conventional git messages will be used. This helps building changelog scaffolding automatically later.
When ready for releasing a particular crate or set of crates of interest, run cargo smart-release [<crate-name> ...]
to simulate a release. For particularly thorough but error-prone simulations (as in false positives) one could run cargo smart-release --dry-run-cargo-publish
. To polish changelogs, run cargo changelog --write <crate-name>
to update the scaffolding and edit it by hand until it fits.
After evaluating the release procedure and following instructions, cargo smart-release --execute
will cause the fully automatic release of one or more crates.
There are various other options that shouldn't be needed in the common case, use cargo smart-release --help
to see them.
Installation
Cargo
Via cargo
, which can be obtained using rustup
cargo install cargo-smart-release
Features
- safe to use as actually performing an operation requires the
--execute
flag - avoid inconsistent states by making operations as atomic as possible, leveraging
gitoxide
technology to the fullest - handle workspace dependencies and cycles gracefully, allowing one invocation to publish multiple crates
- avoid making any releases if there are no changes
- avoid bumping versions if the current version isn't released, allowing you to control the version by editing the cargo manifest
- conventional commit message drive changelog scaffolding and to automatically derive the crate version to publish
- automatically release dependent workspace IDP crates along with the desired one if they changed since their last release
- automatically adjust manifest versions and update manifests of crates which use those whose versions were incremented
- conservatively bump downstream workspace crates in the light of breaking changes, even though these won't be published, making downstream breakage impossible
- use git tags to know if a crate changed at all, skipping publishes if there is no code change at all
- it's too eager to release and there should be a way to control patch releases.
- Handle pre-release versions, like 1.0.0-beta.1
- Support other remote names than 'origin' - currently the latter name is assumed. Fix by getting the remote of the currently checked out branch.
- handle version specifications correctly (tables vs values)
- handle all version comparators correctly (see here for how it's done)
- Automatically detect if crate changes are breaking to suggest the correct version increment
Comparison to cargo release
cargo-release
is the reason this tool exists, as it got me addicted to an all automatic release workflow that knows git. This works perfectly for simple workspaces or single-crate workspaces, as of 2021-08-12, so use it: cargo install cargo-release
.
Here is what cargo smart-release
does differently: "It tries really hard to do what I want most of the time when publishing workspace gitoxide
crates".
be safe to execute, so it's disarmed by default- specify one or more crates, and detect which crates need publishing automatically
- handle dependency cycles in such a way that increases the chances of overall success
- try really hard to not leave the workspace in an inconsistent state when something goes wrong
- be a playground for
gitoxide
to have a reason to make it much more convenient and more feasible for application authors (aka dog-fooding) - create changelogs non-destructively, along with annotated tags and GitHub releases
Limitations
- it requires tables to be used when specifying versions, i.e.
crate = { version = "1" }
instead of `crate = "1". - it gracefully fails when encountering version requirement comparators which are not
^
, like=
- it's tested only by using it on
gitoxide
, there are only very few regression tests with little coverage. - short object ids in changelogs may be ambiguous, as they are unconditionally truncated to 7 characters.
- changelog rewriting of user content will drop links if they are not of the 'inline' form
- it's very young and probably tries to eat underwear
- it needs a git repository to govern the workspace
Changelogs
- When determining if something changed in top-level crates, only the
src/
directory is used, unless there is only a single crate in the workspace. This value is hard-coded. - For change tracking, it will only obtain manifest values once to know where a crate lives, and expects it to not be moved.
- If list items populated by commit messages contain items themselves, round-tripping will fail. Ideally there was a way to parse an item on the same level only.
Acknowledgements
Thanks to cargo-release for showing the way and for incredible fast response times. I'd recommend everyone to participate there instead of writing your own.
Special thanks go to git-cliff which gave me the nudge needed to want to write my own.