#workspace #version #cargo-subcommand #publish #changelog #package #github

bin+lib publish-cool-workspace

Cargo subcommand for releasing crates in workspaces

6 releases

0.13.6 Mar 14, 2023
0.13.5 Nov 17, 2022
0.13.4 Oct 25, 2022

#471 in Cargo plugins

21 downloads per month

MIT/Apache

200KB
5K SLoC

publish-cool-package

This is a fork!

This is a fork of gitoxide/cargo-smart-release. You probably don't want to use this package. This is written to support a specific release flow. https://github.com/Byron/gitoxide

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 cool-workspace

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 ore 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.

Dependencies

~31–61MB
~1M SLoC