Four places told people to write `soulseek-rs-lib = "8"` (RELEASE.md said "6"), and every one of them had been left behind by ten majors or more. The failure is silent rather than loud: 6.x and 8.0.0 are both real published versions, so cargo resolves the snippet happily and hands over a library from August instead of refusing it, and one of the four is soulseek-rs-lib's own README, which is the page crates.io renders. `cargo add` writes whatever version is current at the time it runs, so there is no longer a number in the docs to go stale. The manifest pin in soulseek-rs/Cargo.toml stays as it is — release-plz owns that one and keeps it in step with the release.
110 lines
5.7 KiB
Markdown
110 lines
5.7 KiB
Markdown
# Releasing
|
|
|
|
Releases are automated by [release-plz](https://release-plz.dev). You do not run
|
|
`cargo publish`, edit versions, write changelog entries, or push tags by hand.
|
|
|
|
## How it works
|
|
|
|
1. Merge a PR to `master` using [conventional commits](https://www.conventionalcommits.org)
|
|
(`feat:`, `fix:`, `perf:`, `refactor:`, `docs:`, `chore:`, or a `!` / `BREAKING CHANGE:`
|
|
footer for a major bump).
|
|
2. `.github/workflows/release.yml` opens or updates a **`chore: release vX.Y.Z`** PR. It
|
|
contains the semver bump in `[workspace.package]`, the refreshed `Cargo.lock`, and the
|
|
generated `CHANGELOG.md` entry. Review it like any other PR.
|
|
3. Merging that PR releases, but only once CI has passed on the merge commit — a published
|
|
crates.io version can be yanked but never withdrawn, so the `Wait for CI` job blocks the
|
|
publish until the CI run for that exact commit is green:
|
|
- tags `vX.Y.Z` and creates the GitHub release with the changelog as its notes,
|
|
- publishes `soulseek-rs-lib` then `soulseek-rs` to crates.io (dependency order, waiting
|
|
for the index between them),
|
|
- builds and attaches binaries with `.sha256` checksums for six targets:
|
|
|
|
| Archive | Notes |
|
|
| ------------------------------------------------ | ------------------------------ |
|
|
| `soulseek-rs-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz` | static, any glibc |
|
|
| `soulseek-rs-vX.Y.Z-aarch64-unknown-linux-musl.tar.gz` | static, any glibc |
|
|
| `soulseek-rs-vX.Y.Z-x86_64-apple-darwin.tar.gz` | Intel Mac |
|
|
| `soulseek-rs-vX.Y.Z-aarch64-apple-darwin.tar.gz` | Apple Silicon |
|
|
| `soulseek-rs-vX.Y.Z-x86_64-pc-windows-msvc.zip` | |
|
|
| `soulseek-rs-vX.Y.Z-aarch64-pc-windows-msvc.zip` | |
|
|
|
|
- rewrites `Formula/soulseek-rs.rb` in the `michel/homebrew-tap` repository so
|
|
`brew install michel/tap/soulseek-rs` picks up the new macOS and Linux archives,
|
|
- merges `master` back into `develop`, so the branch the work happens on carries the
|
|
new version and changelog rather than drifting behind them.
|
|
|
|
Both crates always share one version, one tag, and one changelog — see `release-plz.toml`.
|
|
|
|
The version lives in one place, `[workspace.package]` in the root `Cargo.toml`, and
|
|
release-plz owns it. Do not edit it by hand on `develop`: the back-merge relies on
|
|
`develop` never touching that line, and an edit there turns every release into a
|
|
conflict.
|
|
|
|
## Nightly builds
|
|
|
|
`.github/workflows/nightly.yml` builds the tip of `develop` at 02:17 UTC every
|
|
day. It resolves the commit once, builds the same six targets as a numbered
|
|
release, verifies all twelve archives and checksum files as one set, then
|
|
replaces the mutable `nightly` prerelease and tag. The published release is
|
|
smoke-tested through both the curl and wget installer paths.
|
|
|
|
Use **Actions → Nightly → Run workflow** to force a build. The workflow always
|
|
checks out `develop`, regardless of the ref selected in the dispatch form. The
|
|
equivalent command is:
|
|
|
|
```bash
|
|
gh workflow run nightly.yml --ref develop
|
|
```
|
|
|
|
Nightly does not publish crates or update Homebrew. If a target fails, the
|
|
previous nightly release stays available; use a manual run to retry.
|
|
|
|
## One-time repository setup
|
|
|
|
- **Settings → Actions → General → Workflow permissions**: enable *Allow GitHub Actions to
|
|
create and approve pull requests*. Without it the release PR is never opened.
|
|
- **Settings → Secrets and variables → Actions**: add `CARGO_REGISTRY_TOKEN`, a
|
|
[crates.io token](https://crates.io/settings/tokens) scoped to `publish-new` and
|
|
`publish-update`. Without it the tag and GitHub release still happen, but the crates.io
|
|
publish fails.
|
|
- **Homebrew tap**: create a public `michel/homebrew-tap` repository, then add a
|
|
`HOMEBREW_TAP_TOKEN` secret — a fine-grained PAT with *Contents: read and write* on that
|
|
repository only. `GITHUB_TOKEN` cannot reach another repository. The formula itself is
|
|
generated by the workflow; nothing in the tap needs editing by hand.
|
|
|
|
## Notes
|
|
|
|
- A merge with no releasable commits (only `docs:`/`chore:`/`test:`) opens no release PR.
|
|
That is intended.
|
|
- The release PR does not run CI on its own, because GitHub does not trigger workflows for
|
|
PRs opened with `GITHUB_TOKEN`. Pushing any commit to that branch yourself does start it —
|
|
handy if you want the version bump validated before merging.
|
|
- If one target's build fails, the other five still upload (`fail-fast: false`). To retry,
|
|
run the **Release** workflow manually and set `tag` to the existing tag (e.g. `v6.0.0`);
|
|
it rebuilds and re-uploads every target for that tag. Re-running the failed job from the
|
|
Actions UI replays the *old* workflow file, so it is no use when the workflow is the thing
|
|
that needs fixing.
|
|
- To skip a release for a commit that would otherwise trigger one, use a `chore:` type.
|
|
- **If CI flakes on the release commit the publish is blocked, by design.** The e2e suite
|
|
talks to a real soulfind server over the network and does occasionally time out. To
|
|
recover: re-run the failed CI job, wait for that run to go green, then re-run the
|
|
**Release** workflow. The gate reads the *newest* CI run for the commit, so it will then
|
|
pass. Never work around it by publishing by hand.
|
|
- Release binaries are stripped via `[profile.release] strip = true` in the workspace
|
|
`Cargo.toml`, so `cargo install` benefits too — not just the release archives.
|
|
|
|
## Installing a release
|
|
|
|
```bash
|
|
cargo install soulseek-rs
|
|
```
|
|
|
|
Or download an archive from the [releases page](https://github.com/michel/soulseek-rs/releases),
|
|
verify it against the adjacent `.sha256`, and extract the binary.
|
|
|
|
## Using the library
|
|
|
|
```bash
|
|
cargo add soulseek-rs-lib
|
|
```
|