Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
44456e2
fix(desktop): resolve overlapping member mentions (#5225)
atishpatel Aug 10, 2026
5e4c05f
feat(desktop): NIP-AM agent-usage backend — P2 emission/transport/arc…
wpfleger96 Aug 10, 2026
563e434
Reduce repeated ACP session context (#5423)
wesbillman Aug 10, 2026
3c76f68
fix(search): surface exact short profile names (#5480)
wesbillman Aug 10, 2026
c1e20a8
fix(release): pin desktop PR operations to block/buzz (#5212)
wesbillman Aug 10, 2026
43573d1
ci(release): gate OSS desktop auto-update promotion (#5398)
wesbillman Aug 10, 2026
bb9aae1
feat(desktop): time-based sweep for stale localStorage caches (#5453)
wesbillman Aug 10, 2026
9c074bb
fix(desktop): bound nine unbounded localStorage stores (#5454)
wesbillman Aug 10, 2026
5a3b3d2
perf(ci): experiment with sccache for relay builds (#5224)
wesbillman Aug 10, 2026
2777189
fix(channels): restore member invitations to private channels (#5493)
wesbillman Aug 10, 2026
07a3c76
fix(desktop): quiesce renderer polling while hidden (#3677) (#5490)
wesbillman Aug 10, 2026
3f2f326
Polish desktop onboarding flow (#5310)
klopez4212 Aug 10, 2026
f8f2ef0
feat(cli): add --visibility flag to channels update (#5119)
cameronhotchkies Aug 10, 2026
538e5e1
chore(release): release Buzz Desktop version 0.5.9 (#5521)
wesbillman Aug 10, 2026
7e6e9c5
fix(link-preview): restore Buzz entity link cards (#5494)
tellaho Aug 11, 2026
9518445
Merge remote-tracking branch 'upstream/main' into upstream-sync-20260811
adrienlacombe Aug 11, 2026
f36d164
docs(agents): record that rolling latest.json promotion left release.yml
adrienlacombe Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ jobs:
run: scripts/test-release-ref-contract.sh
- name: Desktop release candidate contract
run: scripts/test-desktop-release-candidate.sh
- name: OSS desktop promotion contract
run: |
scripts/test-oss-desktop-promotion.sh
scripts/test-oss-desktop-promotion-behavior.sh
- name: Mobile release contract
run: |
scripts/test-mobile-release-contract.sh
Expand Down Expand Up @@ -317,6 +321,9 @@ jobs:
if: github.event_name == 'push' || needs.changes.outputs.desktop == 'true' || needs.changes.outputs.desktop-rust == 'true' || needs.changes.outputs.rust == 'true'
permissions:
contents: read
env:
SCCACHE_GHA_ENABLED: "true"
SCCACHE_GHA_RW_MODE: ${{ (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.number == 5224)) && 'READ_WRITE' || 'READ_ONLY' }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
Expand All @@ -341,13 +348,22 @@ jobs:
.
desktop/src-tauri
save-if: ${{ github.event_name != 'pull_request' }}
# Cache rustc outputs for unchanged workspace crates. Trusted pushes write;
# the bounded PR 5224 trial writes only to its isolated merge-ref scope.
- name: Set up sccache
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true'
uses: Mozilla-Actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 # zizmor: ignore[cache-poisoning] Bounded trial: only PR 5224 writes to its isolated merge-ref scope; trusted pushes retain production writes.
with:
version: v0.16.0
- name: Install cargo-nextest
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true'
uses: taiki-e/install-action@0fd46367812ee04360509b4169d9f659d6892bb2 # v2.79.15
with:
tool: cargo-nextest@0.9.136
- name: Build relay artifacts
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true'
env:
RUSTC_WRAPPER: sccache
run: |
cargo build --profile ci -p buzz-relay -p git-credential-nostr
cargo nextest archive \
Expand All @@ -359,7 +375,9 @@ jobs:
--test e2e_event_reminder \
--archive-file target/ci/backend-integration-tests.tar.zst
- name: Save relay artifacts cache
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true'
# PR-scoped exact-source entries cannot warm main or other PRs and churn
# the shared cache pool. sccache provides read-only PR reuse instead.
if: steps.relay-artifacts-cache.outputs.cache-hit != 'true' && github.event_name == 'push'
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
with:
path: |
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/promote-oss-desktop-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Promote OSS Desktop Auto-Update
run-name: Promote desktop-v${{ inputs.version }} to auto-update

on:
workflow_dispatch:
inputs:
version:
description: Stable desktop version to promote (X.Y.Z)
required: true
type: string

concurrency:
group: oss-desktop-auto-update-promotion
cancel-in-progress: false

permissions:
contents: read

jobs:
promote:
if: github.repository == 'block/buzz'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Require the reviewed workflow from main
env:
DISPATCH_REF: ${{ github.ref }}
run: |
if [ "$DISPATCH_REF" != "refs/heads/main" ]; then
echo "::error::OSS desktop promotion must be dispatched from main, not $DISPATCH_REF"
exit 1
fi

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Validate and promote exact release manifest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ inputs.version }}
run: scripts/promote-oss-desktop-release.sh "$VERSION"
5 changes: 1 addition & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,7 @@ jobs:
echo "Publishing a manifest for ${#TRIPLES[@]} platform(s)."
bash desktop/scripts/generate-oss-latest-json.sh "$VERSION" "${TRIPLES[@]}" > latest.json
cat latest.json
cp latest.json staged/updater-manifest.json

- name: Create or verify versioned draft
run: |
Expand Down Expand Up @@ -1379,7 +1380,3 @@ jobs:
- name: Publish complete versioned release
if: env.already_published != 'true'
run: gh release edit "desktop-v${VERSION}" --draft=false

- name: Upload latest.json to rolling release last
if: ${{ !contains(needs.setup.outputs.version, '-') }}
run: gh release upload buzz-desktop-latest latest.json --clobber
14 changes: 7 additions & 7 deletions .release/desktop-candidate.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"schema": 2,
"version": "0.5.8",
"base_sha": "6a17d035f79ad582ca3f4f3cdc38d376f2c4087f",
"previous_tag": "desktop-v0.5.7",
"previous_base_sha": "74b913cff8512c015dc6f1a7473b253fa803f954",
"previous_merge_sha": "13c9e900c84cac1e2c8eeb7551bd1510ecb544d3",
"tag": "desktop-v0.5.8",
"commit_count": 4
"version": "0.5.9",
"base_sha": "f8f2ef0440e7a074223ec04dc3b32d817b8b9d9b",
"previous_tag": "desktop-v0.5.8",
"previous_base_sha": "6a17d035f79ad582ca3f4f3cdc38d376f2c4087f",
"previous_merge_sha": "c815a9c6e1a1d1818a0547f60f894e4a5388761a",
"tag": "desktop-v0.5.9",
"commit_count": 29
}
38 changes: 37 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ place.
| `.gitattributes` | `*.lock.yml linguist-generated` | Added by `gh aw init` |
| `ci.yml` | mesh-llm rev read from `desktop/src-tauri/Cargo.lock` | The two locks pin mesh-llm independently (desktop is outside the root workspace) and can name different revs — at the time of the patch, root `tag=v0.73.1` (`43103c5c`) vs desktop `rev=f455d493`. The step fetches the *desktop* manifest, so the root rev names a checkout never fetched. Upstream is masked by a warm cache — the step is skipped on cache hit. **Since the 2026-07-31 sync both locks pin `tag=v0.74.0` (`e60b2fe4`), so the patch is a temporary no-op — do not delete it.** The locks stay independent; the next bump that moves one and not the other re-breaks the root-lock version |
| `docker.yml` | `PUSH_GATEWAY_IMAGE` override; owner-correct attestation hint | Push-gateway image was hardcoded to `ghcr.io/block/buzz-push-gateway` in nine places, so `GHCR_IMAGE` could not retarget it |
| `release.yml` | `RELEASE_REPO` guard on `setup` + `release-linux`; `BASE` and `BUZZ_UPDATER_ENDPOINT` derive from `github.repository`; `assemble-manifest` asserts on job results instead of counting platforms; `release-macos-unsigned` runs without `--no-sign`, sets `BUZZ_MACOS_ADHOC_SIGN=1`, asserts the bundle signature, and builds `buzz-backend-kubernetes` among its sidecars | Guards were pinned to `block/buzz`; the updater URLs were hardcoded to Block's releases, so a fork verified its artifacts against Block's rolling release and shipped builds polling Block for updates. The `-ge 3` platform count was unreachable with both macOS jobs skipped, so `latest.json` was never published. `--no-sign` suppressed updater signing too, so the `.app.tar.gz` shipped with no `.sig`; without ad-hoc signing the bundle had no signature at all and macOS called it damaged — see [Desktop auto-update](#desktop-auto-update-linux--windows--works). **`release-macos-unsigned` is a fork-added job, so upstream's sweeps across its own lanes never reach it.** When upstream added the `buzz-backend-kubernetes` sidecar to every non-Windows lane (#4289) this job kept the old list, and because `tauri.conf.json`'s `externalBin` is shared while `scripts/bundle-sidecars.sh` exits 1 on a missing binary, the fork's only `darwin-aarch64` lane would have failed — with no merge conflict anywhere. Re-check this job's sidecar list whenever upstream touches one of theirs. **Do not name the release-upload command anywhere in this file, even in a comment:** `scripts/test-release-ref-contract.sh` counts occurrences of that string and requires exactly two |
| `release.yml` | `RELEASE_REPO` guard on `setup` + `release-linux`; `BASE` and `BUZZ_UPDATER_ENDPOINT` derive from `github.repository`; `assemble-manifest` asserts on job results instead of counting platforms; `release-macos-unsigned` runs without `--no-sign`, sets `BUZZ_MACOS_ADHOC_SIGN=1`, asserts the bundle signature, and builds `buzz-backend-kubernetes` among its sidecars | Guards were pinned to `block/buzz`; the updater URLs were hardcoded to Block's releases, so a fork verified its artifacts against Block's rolling release and shipped builds polling Block for updates. The `-ge 3` platform count was unreachable with both macOS jobs skipped, so `latest.json` was never published. `--no-sign` suppressed updater signing too, so the `.app.tar.gz` shipped with no `.sig`; without ad-hoc signing the bundle had no signature at all and macOS called it damaged — see [Desktop auto-update](#desktop-auto-update-linux--windows--works). **`release-macos-unsigned` is a fork-added job, so upstream's sweeps across its own lanes never reach it.** When upstream added the `buzz-backend-kubernetes` sidecar to every non-Windows lane (#4289) this job kept the old list, and because `tauri.conf.json`'s `externalBin` is shared while `scripts/bundle-sidecars.sh` exits 1 on a missing binary, the fork's only `darwin-aarch64` lane would have failed — with no merge conflict anywhere. Re-check this job's sidecar list whenever upstream touches one of theirs. **Do not name the release-upload command anywhere in this file, even in a comment:** `scripts/test-release-ref-contract.sh` counts occurrences of that string and, since upstream #5398 moved rolling-manifest promotion out of this file, requires exactly **one** — it was two before the 2026-08-11 sync. `scripts/test-oss-desktop-promotion.sh` additionally asserts that the rolling-release upload does *not* appear here at all, so prose naming it fails two contracts, not one. See [Rolling-manifest promotion](#rolling-manifest-promotion-moved-upstream-and-the-fork-cannot-reach-it) |
| `release.yml` + `macos-canary.yml` | `BUZZ_DESKTOP_BUILD_AUTO_CONNECT_DEFAULT_RELAY: "1"` on the build step of the three fork-runnable lanes and the canary | Skips the "Join or create a community" picker and auto-creates the single allowlisted community. This is **upstream's own opt-in**, for builds whose default relay is reviewed and fixed — no source change was needed. It works because release builds already default to `wss://relay.bitcoinmarkets.app` (`relay.rs` → `relay/allowlist.rs`) and `shouldAutoConnectDefaultRelay` accepts any non-loopback `ws(s)` URL. `option_env!`, so it is **compile-time**: absent at build time it silently does nothing. Deliberately not set on the two `block/buzz` macOS lanes, and irrelevant in debug builds where the loopback default correctly keeps the picker. Assert it with the `#[ignore]`d `compiled_flag_matches_expected` test and `BUZZ_TEST_EXPECTED_AUTO_CONNECT_DEFAULT_RELAY` |
| `desktop/scripts/build-release-config.mjs` | `BUZZ_MACOS_ADHOC_SIGN=1` emits `bundle.macOS.signingIdentity: "-"` | Ad-hoc bundle signing for the one macOS lane nothing else signs. Opt-in and off by default, so the two `block/buzz` lanes still reach `block/apple-codesign-action` unsigned — setting it unconditionally would sign a bundle that is about to be re-signed. It has to be config rather than a post-build `codesign`, because Tauri builds the DMG in the same invocation |
| `linux-canary.yml`, `windows-canary.yml` | `RELEASE_REPO` guard | Were pinned to `block/buzz` |
Expand Down Expand Up @@ -729,6 +729,42 @@ the app checks on mount and every 6 h
`.deb` is not auto-updatable by Tauri constraint (`release.yml:699`), so Linux
auto-update is **AppImage only**.

#### Rolling-manifest promotion moved upstream, and the fork cannot reach it

**As of the 2026-08-11 sync the heading above is aspirational again, and nothing
in CI says so.** Upstream #5398 split publishing the rolling `latest.json` out of
`release.yml` into a separate, **manually dispatched**
`.github/workflows/promote-oss-desktop-release.yml`. `assemble-manifest` still
builds the fork's manifest correctly and still stages it — now as
`updater-manifest.json` on the versioned `desktop-v<version>` release — but the
step that copied it to `buzz-desktop-latest` is gone. Since
`BUZZ_UPDATER_ENDPOINT` points at
`…/releases/download/buzz-desktop-latest/latest.json`, the fork's rolling
manifest now freezes at whatever was last promoted and installed clients stop
seeing new versions. **The merge was clean and every gate passed** — this is the
[clean merge is not a correct merge](#4-a-clean-merge-is-not-a-correct-merge)
failure mode, found by reading the diff at a patch site.

Three things block the fork from dispatching the new workflow, and only the first
is the usual one-line guard:

| Blocker | Where | Note |
|---|---|---|
| `if: github.repository == 'block/buzz'` | `promote-oss-desktop-release.yml` | The ordinary `RELEASE_REPO` treatment. Safe: `test-oss-desktop-promotion.sh` greps only for `if: github.repository ==`, not the literal owner |
| `[[ "$REPOSITORY" == "block/buzz" ]] \|\| fail`, plus two hardcoded `https://github.com/block/buzz/releases/download/…` URL literals | `scripts/promote-oss-desktop-release.sh` | Repo-derivable. No contract pins the owner in the promoter; the URL check is pinned only as the substring `desktop-v" + $version + "/"` |
| `EXPECTED_PLATFORMS` requires **exactly** the four upstream triples | same script | **This is the one that needs a decision, not a patch.** The fork produces three — `release-macos-x64` is pinned to `block/buzz` (`release.yml:273`) so `darwin-x86_64` never exists here, and the live rolling manifest is already `{darwin-aarch64, linux-x86_64, windows-x86_64}`. It cannot simply be relaxed: `test-oss-desktop-promotion-behavior.sh` runs the promoter with `GITHUB_REPOSITORY=block/buzz` and asserts that both a missing platform and an extra platform are *rejected*, so the expected set has to become repo-derived while staying exact per repo |

Do not paper over this by adding an upload back into `release.yml` — that fails
both the `gh release upload` count in `test-release-ref-contract.sh` and the
explicit negative assertion in `test-oss-desktop-promotion.sh`. The promotion
workflow is the intended writer; the fork needs its own path through it.

Worth knowing before testing any of it: the fork's rolling `latest.json` is
currently version **`0.5.100`**, above every real upstream version, and the
promoter refuses downgrades. So even a fully patched promotion would refuse
`0.5.9` until that value is reset — it reads like a forced test value rather than
a real release, and its provenance predates this note.

#### macOS is unsigned, and users must be told what that means

`release-macos-unsigned` supplies `darwin-aarch64`. It mirrors the signed
Expand Down
Loading
Loading