release-plz owns the workspace version and the changelog, and writes both on master. Nothing carried either back, so develop still declared 14.1.2 five releases after v14.1.2 shipped. Nightly builds the tip of develop, which meant every nightly binary reported --version 14.1.2 against a released 18.0.0, and the changelog on the branch the work happens on stopped at v14.1.2 too. The job merges master whole rather than cherry-picking the bump, so the changelog travels with it, and hangs off `release` rather than `binaries` so the sync does not wait on six binary builds. develop never edits those lines itself, which is what keeps the merge clean; a conflict fails the job rather than resolving itself quietly. Nothing in the repository triggers on a push to develop, so this neither loops back into the workflow nor spends a CI run.
5.7 KiB
Releasing
Releases are automated by release-plz. You do not run
cargo publish, edit versions, write changelog entries, or push tags by hand.
How it works
- Merge a PR to
masterusing conventional commits (feat:,fix:,perf:,refactor:,docs:,chore:, or a!/BREAKING CHANGE:footer for a major bump). .github/workflows/release.ymlopens or updates achore: release vX.Y.ZPR. It contains the semver bump in[workspace.package], the refreshedCargo.lock, and the generatedCHANGELOG.mdentry. Review it like any other PR.- 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 CIjob blocks the publish until the CI run for that exact commit is green:-
tags
vX.Y.Zand creates the GitHub release with the changelog as its notes, -
publishes
soulseek-rs-libthensoulseek-rsto crates.io (dependency order, waiting for the index between them), -
builds and attaches binaries with
.sha256checksums for six targets:Archive Notes soulseek-rs-vX.Y.Z-x86_64-unknown-linux-musl.tar.gzstatic, any glibc soulseek-rs-vX.Y.Z-aarch64-unknown-linux-musl.tar.gzstatic, any glibc soulseek-rs-vX.Y.Z-x86_64-apple-darwin.tar.gzIntel Mac soulseek-rs-vX.Y.Z-aarch64-apple-darwin.tar.gzApple Silicon soulseek-rs-vX.Y.Z-x86_64-pc-windows-msvc.zipsoulseek-rs-vX.Y.Z-aarch64-pc-windows-msvc.zip -
rewrites
Formula/soulseek-rs.rbin themichel/homebrew-taprepository sobrew install michel/tap/soulseek-rspicks up the new macOS and Linux archives, -
merges
masterback intodevelop, 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:
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 scoped topublish-newandpublish-update. Without it the tag and GitHub release still happen, but the crates.io publish fails. - Homebrew tap: create a public
michel/homebrew-taprepository, then add aHOMEBREW_TAP_TOKENsecret — a fine-grained PAT with Contents: read and write on that repository only.GITHUB_TOKENcannot 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 settagto 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 = truein the workspaceCargo.toml, socargo installbenefits too — not just the release archives.
Installing a release
cargo install soulseek-rs
Or download an archive from the releases page,
verify it against the adjacent .sha256, and extract the binary.
Using the library
[dependencies]
soulseek-rs-lib = "6"