Files
soulseek-rs-modded/RELEASE.md
T
Michel de Graaf 1b898adeeb docs: stop pinning a library version the instructions cannot keep current
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.
2026-09-10 12:08:00 +02:00

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
```