-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Simplify Release Procedures RFD
This RFD recommends changes to simplify the release processes for Hipcheck, explaining the problems with the current setup, and the benefits of the proposed changes. Signed-off-by: Andrew Lilley Brinker <[email protected]>
- Loading branch information
1 parent
58c57e2
commit e50d297
Showing
1 changed file
with
164 additions
and
0 deletions.
There are no files selected for viewing
164 changes: 164 additions & 0 deletions
164
site/content/rfds/0007-simplified-release-procedures.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
--- | ||
title: "Simplified Release Procedures" | ||
--- | ||
|
||
## The Current Situation | ||
|
||
Currently, the Hipcheck _project_ has the following artifacts we release | ||
periodically. | ||
|
||
- `hc`: The main Hipcheck binary, produced by the `hipcheck` package. | ||
- `hc-update`: The Hipcheck self-updater, generated by `cargo-dist`. | ||
- `hipcheck-macros`: A Hipcheck-internal library. | ||
- Docker image: published to Docker Hub. | ||
|
||
These are published to the following places: | ||
|
||
- `hc`: | ||
- Crates.io (as `hipcheck`) | ||
- GitHub Releases w/ install script generated by `cargo-dist` | ||
- `hc-update`: | ||
- GitHub Releases w/ install script generated by `cargo-dist` | ||
`- `hipcheck-macros`: | ||
- Crates.io | ||
- Docker image: | ||
- Docker Hub | ||
|
||
When we cut a new release of `hc`, the flow has been: | ||
|
||
1. Update the `CHANGELOG.md` for the project with release notes for the new | ||
version, open a PR, and get that merged. | ||
2. Run `cargo release` locally to make a new release of `hc` to Crates.io. | ||
At the end of that process, `cargo release` creates and publishes a tag | ||
for the new version | ||
3. This triggers `cargo-dist`'s CI `release` job on GitHub. This job then | ||
builds our pre-built binaries and produces the GitHub Release with our | ||
install script and the `hc-update` tool. | ||
4. This release triggers our Docker release build, which publishes our image | ||
to Docker Hub. | ||
|
||
## The Problems | ||
|
||
There are quite a few problems with the above setup: | ||
|
||
1. __Inconsistency__: When a user installs `hc` from the install script | ||
built by `cargo-dist` and included in each GitHub Release, they get the | ||
`hc-update` tool, which allows Hipcheck to self-update through the | ||
`hc update` subcommand. This means that users installing from the | ||
install script get a strictly better outcome than users installing from | ||
Crates.io. | ||
2. __Bad Release Staging__: The current setup has, for `hc` at least, | ||
three separate stages of "releasing" a new version, each of which can | ||
fail independently: | ||
1. Publishing to Crates.io with `cargo release` | ||
2. Publishing a GitHub Release with `cargo-dist` | ||
3. Publishing a container image to Docker Hub | ||
|
||
## Proposal | ||
|
||
We institute a new rule: __One Artifact, One Release__. This means, for | ||
any artifact we're publishing, there's exactly _one_ release event | ||
that publishes to _one_ place. | ||
|
||
Let's walk through what this means in more detail, looking first at | ||
`hc`, and then at the soon-to-be-released Rust plugin SDK. | ||
|
||
### Releasing `hc` | ||
|
||
Under this proposal, a release for `hc` would look like this: | ||
|
||
1. Write the `CHANGELOG.md` update for the new version, make a PR, and | ||
get it merged. | ||
2. Tag the new version as `hipcheck-v<NEW_VERSION>`, with `<NEW_VERSION>` | ||
replaced with the SemVer version we're releasing (`X.Y.Z`). | ||
|
||
That's it! Then, `cargo-dist` would build our release artifacts, | ||
including the pre-built binaries and the install scripts, and make the | ||
GitHub Release when it's done. | ||
|
||
Once the GitHub Release is made, the Docker build will run, building | ||
a Docker container to publish with the version of the container image's | ||
`curl | sh` install script set to the just-released version. Since this | ||
image is effectively just a wrapper around this install script, it should | ||
run without issue. | ||
|
||
The `cargo-dist` folks at Axo.dev have expressed an interest in handling | ||
generation and publication of Docker images themselves in the future, which | ||
would fit in nicely with this flow as well. | ||
|
||
Also, if we wanted to generate any additional artifacts for a release in | ||
the future, like SBOMs or SLSA attestations, they'd fit right into this | ||
same process, being attached to the GitHub Release. | ||
|
||
### Releasing `hipcheck-sdk` | ||
|
||
In the near future we'll start publishing a new `hipcheck-sdk` crate which | ||
provides a Rust SDK for plugin authors to use when writing plugins in Rust. | ||
This would be a library, and would be released in its own similar way: | ||
|
||
1. Update the `CHANGELOG.md` for this project to reflect the new version. | ||
Make a PR and get this `CHANGELOG.md` merged. | ||
2. Push a tag for `hipcheck-sdk-v<NEW_VERSION>` with `<NEW_VERSION>` | ||
reflecting the new version. | ||
|
||
We could then have GitHub CI set up to identify the new Git tag pushed, | ||
and run `cargo publish` to publish the new version from CI onto Crates.io. | ||
|
||
This has some nice properties, including automatically permitting anyone | ||
with access to push tags to cut new releases of the crate, and allowing | ||
us to established trusted publication of crates from CI with attestations | ||
in the future. | ||
|
||
## What We'd Lose | ||
|
||
The first, most conspicious thing we'd lose here is that we'd stop | ||
publishing the `hipcheck-macros` crate to Crates.io. This is really a | ||
piece of logic internal to Hipcheck, but is one we have to publish as | ||
a separate crate because it exposes a procedural macro, which needs its | ||
own crate; and that crate has to be public because the `hipcheck` crate | ||
itself is published on Crates.io, and public crates can't have dependencies | ||
published to other registries or not published to a registry at all. | ||
|
||
The second thing we'd lose (though this has substantial benefits) is that | ||
we'd no longer publish the `hipcheck` crate to Crates.io. This means users | ||
would no longer be able to run `cargo install hipcheck` or | ||
`cargo binstall hipcheck` to install Hipcheck locally. This is a reduction | ||
in flexibility for users, but _does_ simplify our processes, make releases | ||
more reliable, and enable us to have more flexibility in the internal | ||
structure of Hipcheck itself. | ||
|
||
Which brings me to a big, but as yet un-discussed, benefit… | ||
|
||
## Vendoring Salsa | ||
|
||
The thing that finally tipped me over into wanting to pursue this | ||
simplification was the looking challenge of vendoring the `salsa` crate. | ||
`salsa` is a Rust crate for incremental computation which we rely on | ||
heavily within Hipcheck. Unfortunately, the maintainers of `salsa` stopped | ||
publishing releases to Crates.io years ago, and `salsa` itself has gone | ||
through 1 major refactor, with a second currently underway, entirely away | ||
from the public versions. If you want to depend on `salsa` as published | ||
to Crates.io, you have to use `salsa` 1.0, which is no longer supported | ||
and has a number of deficits. | ||
|
||
Normally, this isn't a problem, as users of `salsa` can specify it as a | ||
`git` dependency in their `Cargo.toml` file, and use the `package` key on | ||
the dependency to specify the `salsa-2022` package (the 1st majorly-rewritten | ||
version, now itself in the process of being replaced by Salsa 3.0). However, | ||
because `hipcheck` has so far been published to Crates.io, this option is not | ||
available to us. If we wanted to use the newer versions of `salsa` ourselves, | ||
we'd need to vendor them into some sort of `hipcheck-incremental` crate, | ||
which we'd publish to Crates.io ourselves, and which we'd need to sync with | ||
the upstream Salsa project periodically. | ||
|
||
We _did_ tinker with some efforts to do this, but quickly found it to be | ||
reasonably complicated to do. We do not believe pursuing this or maintaining | ||
this vendored version over the long term would be a good use of the team's | ||
time and effort. | ||
|
||
Finally, pursuing this would raise the additional question of the value of | ||
exposing these "should-be-internal-but-have-to-be-external" crates, | ||
`hipcheck-macros` and `hipcheck-incremental`. Neither are intended for others | ||
to use, and while we can certainly _document_ this and tell people not to use | ||
them, we can't _stop_ anyone from using them, and exposing these APIs publicly | ||
is awkward and creates risk and complexity for the Hipcheck project. |