Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
9.0 KiB
Releasing Buzz
Buzz has three independent release lanes, each driven by a release PR — no human ever pushes a git tag:
| Lane | Recipe | Artifact |
|---|---|---|
| Desktop | just release-desktop |
Signed desktop app (macOS/Linux) |
| Relay | just release-relay |
ghcr.io/block/buzz container image |
| Mobile | just release-mobile |
Buzz mobile app (tag is the sprout_ref for the internal build) |
The three lanes version independently: the desktop version lives in
desktop/package.json, the relay version in crates/buzz-relay/Cargo.toml, and
the mobile version in mobile/pubspec.yaml.
The mobile lane publishes a mobile-v<version> tag that is consumed
manually, cross-repo, as the sprout_ref input to the internal
buzz-releases Buildkite pipeline (iOS dogfood → Block Comp Portal, App Store →
TestFlight — see Internal Releases). The OSS lane is
tag-only by design: OSS block/buzz CI cannot trigger CI in the private
buzz-releases repo (infosec), so a human cuts the internal build from the tag
rather than auto-dispatching across that boundary.
Quick Start
# Desktop release (next patch version)
just release-desktop
# Desktop patch / minor / explicit
just release-desktop patch
just release-desktop 0.4.0
just release-desktop 1.0.0
# Relay release (same argument forms)
just release-relay
just release-relay 0.4.0
# Mobile release (same argument forms)
just release-mobile
just release-mobile 0.4.0
just release-desktop creates a version-bump/<version> PR; just release-relay creates a relay-release/<version> PR; just release-mobile
creates a mobile-release/<version> PR. Each bumps its own version manifest,
regenerates lockfiles, and appends a changelog entry. Merge the PR to trigger
the build automatically (the mobile tag is instead the sprout_ref a human
feeds the internal build — see above).
Re-running any of these recipes with the same version is safe — it detects the
existing branch and PR, resets to current main, regenerates the changelog
with any new commits, and updates the PR in place.
How It Works
All three lanes share one engine; they differ only in which version manifest they bump, which branch prefix they use, and what the merge triggers.
Desktop
just release-desktopruns locally onmain— computes the next version, creates (or reuses) aversion-bump/<version>branch, bumps the desktop manifests, regenerates lockfiles, generates a changelog entry inCHANGELOG.md, commits, pushes, and opens (or updates) a PR.- Merge the PR — the
auto-tag-on-release-pr-mergeworkflow detects theversion-bump/*branch merge and pushes av<version>tag. - Tag triggers
release.yml— builds, signs, notarizes, and publishes the desktop app for macOS and Linux.
Relay
just release-relayruns locally onmain— computes the next relay version, creates (or reuses) arelay-release/<version>branch, bumpscrates/buzz-relay/Cargo.toml, regeneratesCargo.lock, generates a changelog entry incrates/buzz-relay/CHANGELOG.md, commits, pushes, and opens (or updates) a PR.- Merge the PR — the
auto-tag-on-release-pr-mergeworkflow detects therelay-release/*branch merge and pushes arelay-v<version>tag. - Auto-tag dispatches
docker.yml— the same workflow then triggersdocker.ymlwith the version and tag ref, which builds the multi-arch relay image and publishesghcr.io/block/buzz:<version>(plus:<major>.<minor>,:<major>, and:latestfor stable releases). Prereleases (relay-v<version>-rc.1) publish only the prerelease tag and do not move:latest. (The dispatch — rather than relying ondocker.yml'spush: tagstrigger — is required because GitHub suppresseson: pushfor tags pushed by the workflow's ownGITHUB_TOKEN; the desktop lane dispatchesrelease.ymlfor the same reason.)
Every push to main continues to build and publish :main + :sha-<7> tags
(the rolling development image). The :latest tag tracks the latest stable
relay release only — it does not move on main pushes or prereleases.
Mobile
just release-mobileruns locally onmain— computes the next mobile version, creates (or reuses) amobile-release/<version>branch, bumpsmobile/pubspec.yaml(preserving the+buildnumber), regeneratesmobile/pubspec.lock, generates a changelog entry inmobile/CHANGELOG.md, commits, pushes, and opens (or updates) a PR.- Merge the PR — the
auto-tag-on-release-pr-mergeworkflow detects themobile-release/*branch merge and pushes amobile-v<version>tag. - The tag is consumed manually, cross-repo — nothing in OSS
block/buzzbuilds on the tag (OSS CI must not trigger CI in the privatebuzz-releasesrepo — infosec). A human feeds themobile-v<version>tag as thesprout_refinput to the internalbuzz-releasesBuildkite pipeline, which builds and ships iOS to Block Comp Portal (dogfood) and TestFlight (App Store, opt-in). See Internal Releases.
Release Types
The argument forms below apply to release-desktop, release-relay, and
release-mobile:
| Command | Version | Example |
|---|---|---|
just release-desktop |
Next patch | 0.3.0 → 0.3.1 |
just release-desktop patch |
Next patch | 0.3.0 → 0.3.1 |
just release-desktop 0.4.0 |
Explicit minor | 0.3.1 → 0.4.0 |
just release-desktop 1.0.0 |
Explicit | 1.0.0 |
Version Files
just bump-desktop-version <version> (desktop lane) updates these files:
| File | Field |
|---|---|
desktop/package.json |
"version" |
desktop/src-tauri/tauri.conf.json |
"version" |
desktop/src-tauri/Cargo.toml |
version (under [package]) |
It also regenerates pnpm-lock.yaml and desktop/src-tauri/Cargo.lock.
just bump-relay-version <version> (relay lane) updates
crates/buzz-relay/Cargo.toml (version under [package]) and regenerates the
workspace Cargo.lock.
just bump-mobile-version <version> (mobile lane) updates
mobile/pubspec.yaml (version:, preserving the +build number) and
regenerates mobile/pubspec.lock.
Manual Fallback
If the automated flow isn't suitable (e.g., building from a non-main ref):
- Go to Actions > Release in the GitHub UI
- Click Run workflow
- Provide the semver version (no
vprefix) and the ref to build from
Internal Releases
After the OSS release ships, trigger an internal build via the sprout-releases Buildkite pipeline. See the buzz-releases README for the full step-by-step instructions and input field reference.
What Gets Published
Each release produces two GitHub releases:
-
v<version>— the user-facing release with the.dmginstaller (macOS). -
buzz-desktop-latest— a rolling pre-release for the Tauri auto-updater containinglatest.json, the signed.tar.gzarchive, and its.sigsignature.
Platform Support
The release workflow builds two separate macOS DMGs — Apple
Silicon (darwin-aarch64, the release job) and Intel
(darwin-x86_64, the release-macos-x64 job) — plus Linux .deb and
.AppImage. Both macOS DMGs are codesigned, notarized, and attached to
the same v<version> release. Intel users download the _x64.dmg.
Prerequisites
- Write access to the
block/buzzGitHub repository ghCLI authenticated (gh auth status)- The following GitHub Actions secrets must be configured:
Secret Purpose BUZZ_UPDATER_PUBLIC_KEYTauri updater public key (minisign) TAURI_SIGNING_PRIVATE_KEYTauri updater private key TAURI_SIGNING_PRIVATE_KEY_PASSWORDPassword for the private key
Troubleshooting
just release-desktop fails with "must be on main branch"
Switch to main and pull latest before running the release recipe.
just release-desktop fails with "working tree is dirty"
Commit or stash your changes before running the release recipe.
New commits merged after creating the release PR
Re-run the release recipe (just release-desktop, just release-relay, or just release-mobile) from an up-to-date main. It resets the branch to current main, regenerates the changelog and PR body to include the new commits, and force-pushes the updated branch.
Build fails at "Validate version"
The version string must be valid semver: MAJOR.MINOR.PATCH with an optional pre-release suffix. Do not include a v prefix.
Auto-updater reports "no update available"
Verify that the buzz-desktop-latest release exists and contains a
valid latest.json. The auto-updater manifest currently lists
darwin-aarch64 only, so Intel and Linux users do not yet receive
auto-updates — they download new versions manually from the release
page. (Adding their entries to latest.json is a follow-up.)