Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Byron/cargo-smart-release

Release complex cargo-workspaces automatically with changelog generation, used by `gitoxide`
https://github.com/Byron/cargo-smart-release

Last synced: 4 days ago
JSON representation

Release complex cargo-workspaces automatically with changelog generation, used by `gitoxide`

Awesome Lists containing this project

README

        

# `cargo smart-release`

Fearlessly release workspace crates and with beautiful semi-handcrafted changelogs.

[![asciicast](https://asciinema.org/a/65uPfzoWxGac43zEZ1gQ1yVVe.svg)](https://asciinema.org/a/65uPfzoWxGac43zEZ1gQ1yVVe)

## 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](https://www.youtube.com/watch?v=EOft_uMDVYE), and the same in 30 minutes is [also available](https://youtu.be/a4CzzxJ7ecE).

## 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 [ ...]` 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 `
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.

[conventional]: https://www.conventionalcommits.org

## Installation

### Cargo
Via `cargo`, which can be obtained using [rustup][rustup]

```
cargo install cargo-smart-release
```

## Features

* [x] safe to use as actually performing an operation requires the `--execute` flag
* [x] avoid inconsistent states by making operations as atomic as possible, leveraging `gitoxide` technology to the fullest
* [x] handle workspace dependencies and cycles gracefully, allowing one invocation to publish multiple crates
* [x] avoid making any releases if there are no changes
* [x] avoid bumping versions if the current version isn't released, allowing you to control the version by editing the cargo manifest
* [x] [conventional] commit message drive changelog scaffolding and to automatically derive the crate version to publish
* [x] automatically release dependent workspace IDP crates along with the desired one if they changed since their last release
* [x] automatically adjust manifest versions and update manifests of crates which use those whose versions were incremented
* [x] conservatively bump downstream workspace crates in the light of breaking changes, even though these won't be published, making downstream breakage impossible
* [x] 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)](https://github.com/Byron/cargo-release/blob/master/src/cargo.rs#L179:L207)
* [ ] handle all version comparators correctly (see [here](https://github.com/Byron/cargo-release/blob/master/src/version.rs#L192:L226) 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.

[cargo-release]: https://github.com/sunng87/cargo-release/issues/224
[git-cliff]: https://github.com/orhun/git-cliff
[rustup]: https://rustup.rs/