Skip to content

feat(release): make desktop releases immutable - #3568

Merged
wesbillman merged 5 commits into
mainfrom
carl/immutable-desktop-release
Jul 30, 2026
Merged

feat(release): make desktop releases immutable#3568
wesbillman merged 5 commits into
mainfrom
carl/immutable-desktop-release

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

Summary

  • add a manual desktop release preparer that regenerates one version-only candidate from current origin/main
  • validate deterministic complete changelog accounting, candidate authorship, allowed files, exact-head approval, required checks, and two-parent merge topology before tagging the reviewed candidate
  • move desktop tags/releases from v* to desktop-v* while preserving relay, chart, push-chart, and mobile behavior
  • stage all four platform outputs in Actions artifacts and grant GitHub release write access only to one final all-platform-gated publisher
  • publish the versioned release only after complete artifact assembly; update stable latest.json last; never promote prereleases or published rebuild outputs

Safety properties

  • desktop tags point to the reviewed candidate SHA, not the merge commit
  • release builds remain tag-bound and reverify tag == checked-out HEAD
  • one final writer fails closed on artifact basename collisions
  • per-tag concurrency serializes publication without cancellation
  • published reruns do not replace immutable versioned assets or promote signatures from a rebuild
  • candidate branches use an explicit remote OID lease when regenerated

Validation

  • scripts/test-desktop-release-candidate.sh
  • scripts/test-release-ref-contract.sh
  • scripts/test-mobile-release-contract.sh
  • changed workflow YAML parsing (Ruby Psych)
  • changed shell syntax (bash -n)
  • git diff --check
  • push hooks: branch-skew, Rust workspace tests (1,853 passed), desktop Tauri tests (3 passed)

Coordinated companion

  • squareup/buzz-releases#79 updates the manually entered desktop source-tag contract to stable-only desktop-v*
  • merge the private contract companion before the first namespaced desktop release

Rollout blockers (no settings changed here)

Before the first candidate/release:

  1. enable merge commits in repository settings
  2. allow merge in ruleset 13596885
  3. require approval after the last push in ruleset 13596885
  4. include refs/tags/desktop-v* explicitly in release ruleset 14378754
  5. prove the non-publishing candidate/merge/tag/artifact validation path before any production release

Do not test the old workflow with a prerelease: it can still mutate the production rolling updater release.

Generate a deterministic version-only candidate, verify its exact reviewed
head and merge topology before tagging, and bind publication to the candidate
with a desktop-specific tag namespace.

Stage every platform artifact before a single final writer publishes the
versioned release and stable updater manifest.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
@wesbillman
wesbillman requested a review from a team as a code owner July 29, 2026 15:39
Comment thread .github/workflows/prepare-desktop-release.yml Fixed
@wesbillman
wesbillman marked this pull request as draft July 29, 2026 17:00
wesbillman and others added 4 commits July 29, 2026 12:55
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Carry the release workflow onto the latest production source, including the
Ubuntu 24.04 Linux packaging fix.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Match GitHub's required-check semantics while still evaluating only the newest
completed run, so path-filtered checks do not prevent desktop tag creation and
stale successes cannot hide a newer failure.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Match the camelCase GraphQL response key and cover approved, rejected,
missing, and null review-decision fixtures.

Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
@cameronhotchkies cameronhotchkies added the triage-ready Appropriate for agentic review label Jul 30, 2026
@wesbillman
wesbillman marked this pull request as ready for review July 30, 2026 18:27
@wesbillman
wesbillman merged commit 1dfd89e into main Jul 30, 2026
26 checks passed
@wesbillman
wesbillman deleted the carl/immutable-desktop-release branch July 30, 2026 18:28
wpfleger96 added a commit that referenced this pull request Jul 30, 2026
…chive

* origin/main:
  Fix video reviews in thread replies (#3719)
  feat(release): make desktop releases immutable (#3568)
  Make relay reconnect backoff authoritative (#3774)
  feat(desktop): add password-protected backups in settings (#3701)

Signed-off-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
adrienlacombe added a commit to adrienlacombe/buzz that referenced this pull request Jul 30, 2026
PR #7 landed upstream's *content* but not its history. gh-aw's
create-pull-request safe output ships the agent's work as a git patch
(`/tmp/gh-aw/aw-*.patch`, upstream-sync.lock.yml:1040), and a patch cannot
carry a merge commit's second parent. So b111a7b arrived with a single
parent despite its "Merge remote-tracking branch 'upstream/main'" subject,
the merge base stayed at 63496cc, and GitHub kept reporting this fork 23
commits behind while those commits' changes were already in the tree.

This is a real `git merge upstream/main`, so the merge base finally advances.
Future syncs become incremental instead of re-resolving the same conflicts
against a stale base every night.

Three files conflicted, all already on the fork-local patch list:

- desktop/src-tauri/src/lib.rs — both sides inserted a `mod` after
  `mod huddle;`: ours `linux_media` via the flattened patch, upstream
  `key_backup`. Union, alphabetical order kept.
- Cargo.lock — `rlp` is fork-local and sits immediately before `rmcp`, which
  upstream touched. Pure union, checked with `cargo metadata --locked`.
- .github/workflows/release.yml — see below.

Two regressions the auto-merge introduced silently, both in release.yml, and
neither raised as a conflict:

1. `assemble-manifest`'s gate. Upstream block#3568 added
   `needs.release.result == 'success'` plus the same for
   `release-macos-x64`. Both jobs are pinned to `block/buzz` and so always
   report `skipped` here, making the gate unsatisfiable in a fork — the exact
   failure 67917a9 fixed, where every updater archive and .sig uploaded and
   only latest.json was missing. Git saw no conflict because our side had
   *removed* a condition while upstream *added* these. Re-patched to accept
   either darwin-aarch64 lane and to tolerate `skipped` only for the signed
   x64 lane, so on block/buzz every lane must still succeed.

2. `release-macos-unsigned` was stranded on the pre-block#3568 release model.
   Upstream moved every platform lane to handing assemble-manifest a
   `desktop-release-*` workflow artifact; this lane is fork-local, so neither
   the restructure nor the `v` -> `desktop-v` tag rename reached it. Left
   alone it would `gh release upload` to a `v${VERSION}` tag that is no
   longer created, and its updater archive would never reach `staged` —
   leaving the fork's only darwin-aarch64 asset out of both the release and
   latest.json, which is the failure this lane exists to prevent. Ported to
   upload-artifact, tag prefix corrected, and `contents` dropped to `read`
   now that it touches no release.

Verified: `cargo check --manifest-path desktop/src-tauri/Cargo.toml
--all-targets` clean, `cargo metadata --locked` clean, release.yml parses,
and the fork-local relay allowlist, productName, APP_DISPLAY_NAME, app_name,
GHCR overrides and mesh-llm-rev patches all survived the merge.

Signed-off-by: adrienlacombe <6303520+adrienlacombe@users.noreply.github.com>
adrienlacombe added a commit to adrienlacombe/buzz that referenced this pull request Jul 30, 2026
…nces

The sync agent ran `git merge` correctly and kept the merge commit, exactly as
its prompt says to, and still produced a single-parent commit on every run.
gh-aw's create-pull-request safe output moves the agent's work into a separate
job as a git patch (`/tmp/gh-aw/aw-*.patch`), and a patch carries file deltas
but not a merge commit's second parent.

The effect was invisible in the diff and obvious in the graph: PR #7 landed all
17 commits' content, the merge base stayed at 63496cc, and GitHub kept
reporting the fork 23 commits behind. Each night then re-merged from that same
stale base and re-resolved the same conflicts. Repaired by hand in 3ce7c8a.

None of that was a reasoning failure, so a better model would not have fixed
it. What matters is who pushes. So the merge moves to a plain workflow with no
AI in it — the runner pushes, and the merge commit that lands is the one git
made, with both parents.

Two stages, split along whether judgement is actually required:

- 01:30 UTC, upstream-sync-merge.yml: fetch, exit if not behind, exit if a sync
  PR is already open, `git merge --no-ff`. Clean merges become a PR. Conflicts
  abort and hand off. This is ~90% of days and costs no AI credits.
- 02:00 UTC, the existing agentic run: now stops if a pushed sync branch already
  contains upstream/main, so it cannot stack a second PR on the 01:30 one. Its
  prompt also no longer claims to preserve upstream history, and says to state
  in the PR body that the merge base will not advance without a manual re-merge.

Deliberately still opens a PR rather than pushing to main: the PR is the review
gate for changes this fork did not author, and deploy-aws.yml deploys every push
to main to the live relay.

Neither stage can catch a merge that is clean but wrong — upstream block#3568
auto-merged without conflict and still broke two fork-local patches in
release.yml. Both the PR body and AGENTS.md now say to read the diff anyway.

AGENTS.md: rewrote "How the sync works", which claimed upstream history stays
intact; that was the assumption the bug hid behind. Added rows for the two new
workflows, the CI-status watcher that was never listed, the linux_media patch
from dabf964, and the NIP-SW Starknet code in ingest.rs and builders.rs —
fork divergence in upstream files that the table did not record at all.

Signed-off-by: adrienlacombe <6303520+adrienlacombe@users.noreply.github.com>
wpfleger96 added a commit that referenced this pull request Jul 30, 2026
* origin/main: (59 commits)
  Fix video reviews in thread replies (#3719)
  feat(release): make desktop releases immutable (#3568)
  Make relay reconnect backoff authoritative (#3774)
  feat(desktop): add password-protected backups in settings (#3701)
  fix(desktop): reuse profiles when joining communities (#2155)
  Render mobile agent mention chips (#3702)
  fix(catalog): update Amp description (#3758)
  fix(acp): preserve truncated thread context (#3340)
  feat(catalog): resolve publisher display name in catalog detail pane (#3640)
  feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741)
  docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163)
  Refine agent sharing dialog (#3699)
  desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607)
  fix: align responsive agent views (#3688)
  Add macOS agent menu-bar menu (#3565)
  Fix pending message feedback (#3543)
  fix(desktop): remove remaining Projects panel fills (#3742)
  feat(mobile): desktop-parity emoji and thread experience (#3485)
  desktop: restore direct community member adds (#3634)
  fix(desktop): explain open agent access (#2561)
  ...

# Conflicts:
#	desktop/scripts/check-file-sizes.mjs
joahg added a commit to joahg/buzz-dev-mode that referenced this pull request Jul 30, 2026
…-style

* origin/main:
  feat(desktop): improve agent activity header ui (block#3321)
  perf(presence): reduce heartbeat frequency (block#3783)
  Tighten continuation message rows (block#3724)
  Fix video reviews in thread replies (block#3719)
  feat(release): make desktop releases immutable (block#3568)
  Make relay reconnect backoff authoritative (block#3774)
  feat(desktop): add password-protected backups in settings (block#3701)
  fix(desktop): reuse profiles when joining communities (block#2155)

Signed-off-by: Joah Gerstenberg <joah@squareup.com>
wpfleger96 pushed a commit that referenced this pull request Jul 30, 2026
* origin/main: (29 commits)
  feat(desktop): raise the install ceiling and make installs observable (#3368)
  fix(db): isolate usage metrics advisory-lock test on scratch DB (#3670)
  Add Devin as a preset ACP harness (#3225)
  feat(desktop): improve agent activity header ui (#3321)
  perf(presence): reduce heartbeat frequency (#3783)
  Tighten continuation message rows (#3724)
  Fix video reviews in thread replies (#3719)
  feat(release): make desktop releases immutable (#3568)
  Make relay reconnect backoff authoritative (#3774)
  feat(desktop): add password-protected backups in settings (#3701)
  fix(desktop): reuse profiles when joining communities (#2155)
  Render mobile agent mention chips (#3702)
  fix(catalog): update Amp description (#3758)
  fix(acp): preserve truncated thread context (#3340)
  feat(catalog): resolve publisher display name in catalog detail pane (#3640)
  feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741)
  docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163)
  Refine agent sharing dialog (#3699)
  desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607)
  fix: align responsive agent views (#3688)
  ...

Signed-off-by: npub1g8493u0xfsjrvflg4n08ezd7vec99mnwzlv0qgwpr9d7gvjwhuzqx59rhw <41ea58f1e64c243627e8acde7c89be667052ee6e17d8f021c1195be4324ebf04@buzz.block.builderlab.xyz>
tellaho pushed a commit that referenced this pull request Jul 30, 2026
* origin/main:
  fix(desktop): allow linux-only media items as dead code off-linux (#3811)
  fix(desktop): report authenticated relay recovery (#3812)
  fix(desktop): don't gate hover affordances on the hover media query (#3657)
  feat(relay): gate kind 30178 team-catalog reads behind the shared tag (#3358)
  test(desktop): click visible thread collapse guide (#3800)
  feat(desktop): raise the install ceiling and make installs observable (#3368)
  fix(db): isolate usage metrics advisory-lock test on scratch DB (#3670)
  Add Devin as a preset ACP harness (#3225)
  feat(desktop): improve agent activity header ui (#3321)
  perf(presence): reduce heartbeat frequency (#3783)
  Tighten continuation message rows (#3724)
  Fix video reviews in thread replies (#3719)
  feat(release): make desktop releases immutable (#3568)
  Make relay reconnect backoff authoritative (#3774)
  feat(desktop): add password-protected backups in settings (#3701)
  fix(desktop): reuse profiles when joining communities (#2155)

Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage-ready Appropriate for agentic review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants