镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

feat(releases): publish desktop download manifest - #3154

Merged
matt2e merged 5 commits into
mainfrom
tho/buzz-release-download-manifest
Nov 10, 2026
Merged

matt2e merged 5 commits into
mainfrom
tho/buzz-release-download-manifest

Conversation

@tellaho

@tellaho tellaho commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Category: improvement

User Impact: The website can link to the current stable release's installers without querying the GitHub releases API.

Problem: The updater feed contains update archives rather than all user-facing installers, and release-hosted JSON cannot be read directly by cross-origin website JavaScript.

Solution: Publish a complete five-installer downloads.json on a dedicated download-feed branch after each approved stable feed promotion, so the website offers the release installed stable apps receive. Previews and betas never change it. Raw GitHub serves the catalog with CORS support. Until the first stable promotion the URL returns 404 and the website should fall back to the releases page.

File changes

.github/workflows/desktop-stable-feed.yml
Publish the download catalog after stable feed promotion and read-back, in the same approved job.

scripts/download-manifest.mjs
Define and validate the versioned five-installer contract (channel: "stable", X.Y.Z only) against actual nonempty assets of a non-prerelease release.

scripts/publish-desktop-downloads.mjs
Follow stable-feed/latest.json. Provide a read-only default and explicit apply mode. Create the isolated data branch initially, update with the existing file SHA, reject rollback, and verify read-back.

tests/integration/desktop-downloads.test.mjs
Exercise creation, updates, dry runs, recovery, malformed assets, prerelease/beta/preview rejection, conflicting writes, and workflow ordering; assert preview promotion never publishes it.

docs/releases.md
Document the public schema, publication/recovery commands, caching and retention.

Reproduction steps

  1. After merge and the first approved desktop-stable-feed.yml run (e.g. -f version=1.0.0), the job publishes https://github.com/raw/block/buzz-app/download-feed/downloads.json.
  2. From an authenticated checkout, GH_REPO=block/buzz-app bin/node scripts/publish-desktop-downloads.mjs 1.0.0 prints all five exact installer URLs without writing anything; --apply recovers the current promoted stable version.
  3. Verify an anonymous browser can read that URL and navigate to both DMGs, the Windows installer, AppImage and DEB.

Validation

  • Originally preview-only (validated at 943b976ae against promoted 0.7.0-preview.260.1). Retargeted to the stable track at 21a36c4d1 per review; preview cleanup changes were dropped because stable releases are never pruned.
  • At 21a36c4d1: full Node integration suite 307/309 passed, one skipped, one failed: macOS launchers preserve icon, port, explicit config and runner arguments, the same pre-existing fixture failure seen on base. The workflow-ordering test fails if the stable feed job stops publishing.
  • Pre-commit and pre-push hooks passed.
  • No stable release exists yet, so the live dry run, Actions-token write path and anonymous read remain to be checked at the first stable promotion. No data branch or release was changed during validation.

@tellaho

tellaho commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Review round 1

No blocking issues. The order is right: publish runs after the feed read-back and before cleanup, and cleanup refuses to run without valid download metadata. Rulesets don't cover download-feed, and the step reuses the job's existing contents: write token.

  • Low: a failed publish runs after the updater feed has already advanced. The run goes red and cleanup is skipped, so the website stays on the previous installers. That's the intended fail-closed path, and it's documented. No change needed.
  • Low: rollback is rejected by design. Promoting an older build to recover the feed would fail the publish step. The docs already say to recover by promoting a higher build. No change needed.
  • Low: test volume. Tests are about 52% of the additions. Consolidate overlapping publisher scenarios and repeated setup, keeping the distinct failure modes.
  • CI: the current failures (a Rust credential-peer test and three browser-journey shards) are outside this diff. Failed jobs are rerunning.

@tellaho
tellaho marked this pull request as ready for review November 10, 2026 00:46
@tellaho
tellaho requested a review from a team as a code owner November 10, 2026 00:46
@matt2e
matt2e force-pushed the tho/buzz-release-download-manifest branch from 8b86fa4 to 43b3036 Compare November 10, 2026 04:31

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Review at 43b303654, against current main (b3ed2397b). The branch base bd344a52d predates #3150. git merge-tree reports no conflicts, but the merged result is broken.

[P1] Automatic promotions pass an empty version: .github/workflows/release.yml:357
The new step uses VERSION: ${{ inputs.promote_version || needs.build.outputs.version }}. #3150 renamed that job to desktop. After the merge, promote_preview has needs: [desktop], and the preceding feed step uses needs.desktop.outputs.version.

On automatic (non-dispatch) runs, VERSION is empty, so assert.match(version, previewVersionPattern) throws. This happens after the updater feed has already moved:

  • the job fails;
  • downloads.json is never published;
  • cleanup (if: success()) is skipped, so previews accumulate.

Manual promote_version dispatches are unaffected. Fix: rebase onto main and use needs.desktop.outputs.version.

[P2] The workflow-ordering test passes even when the order is wrong after rebase: tests/integration/desktop-downloads.test.mjs:136-140
The test locates read-back via a step whose run contains cmp "$RUNNER_TEMP/candidate/latest.json". On main, that cmp now lives in scripts/promote-updater-feed.sh, so findIndex returns -1 and publication > -1 is always true. The test also does not check the VERSION expression.

I ran desktop-downloads.test.mjs and desktop-release.test.mjs on the merged tree with dependencies freshly installed: 15/15 passed despite the P1. Fix: anchor on the promote-updater-feed.sh preview-feed step, and assert that the publish step uses the same VERSION expression as the feed step.

[P2, needs a decision] downloads.json remains preview-only after the stable lane: scripts/download-manifest.mjs:27,37,48
validateDownloadManifest and buildDownloadManifest hard-code channel: "preview" and prerelease: true. installerUrls accepts only preview versions. Only release.yml writes the file; desktop-stable.yml and desktop-stable-feed.yml do not.

Once v1.0.0 is marked Latest, the single public downloads.json will still direct website downloads to previews. Changing that later requires a schema change and an update to the prune validator.

If the website should follow stable, add a channel key or a separate stable file, written by the stable-feed dispatch. If preview-only is intended, document that in docs/releases.md.

Scores: minimalness 9/10, elegance 8/10, correctness 5/10.

  • Elegance: this adds a third copy of the preview-version regex (also in preview-feed.mjs and promote-updater-feed.sh), and the schema fixes channel.
  • Correctness: the P1 breaks every automatic promotion once merged.

Not approved.

tellaho and others added 4 commits November 10, 2026 16:09
Publish the promoted preview installer catalog on an isolated data branch and retain both updater and website selections during cleanup.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
The cleanup script already imports from download-manifest.mjs, so take
previewVersionPattern from there instead of keeping its own copy of the
regex.

preview-feed.mjs keeps its own pattern and comparator: its test copies
the script alone into a temp directory to swap the signing key, so a
sibling import would not resolve there.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
main renamed the preview build job from `build` to `desktop` (#3150),
so after rebasing, the download-manifest step's
`needs.build.outputs.version` resolved to an empty string on automatic
promotions. The step then failed after the updater feed had moved,
skipping downloads.json and preview cleanup. Use the same VERSION
expression as the preceding updater-feed step.

The ordering test anchored on a `cmp` call that now lives in
promote-updater-feed.sh, so findIndex returned -1 and the order check
passed vacuously. Anchor on the `promote-updater-feed.sh preview-feed`
step, require every step to be found, and require the publish step's
VERSION to match the feed step's. The old test passed against the stale
expression; the new one fails on it and passes after the fix.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matt2e
matt2e force-pushed the tho/buzz-release-download-manifest branch from 43b3036 to fbdd123 Compare November 10, 2026 05:14
@matt2e

matt2e commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

🤖 Addressed the review at 43b303654 in fbdd12331, rebased onto current main (b3ed2397b, which includes #3150).

Fixed

  • P1 – empty VERSION on automatic promotions (.github/workflows/release.yml): the publish-downloads step now uses ${{ inputs.promote_version || needs.desktop.outputs.version }}, the same expression as the updater-feed step. That was the only stale needs.build reference this PR added.
  • P2 – vacuous workflow-ordering test (tests/integration/desktop-downloads.test.mjs): the test now anchors on the promote-updater-feed.sh preview-feed step, asserts that the feed, publish and prune steps all exist (index ≥ 0) and run in that order, and asserts the publish step's VERSION matches the feed step's. Checked that the new assertions fail against the old needs.build expression and pass after the fix.

Tests on the rebased tree: desktop-downloads 6/6, desktop-release 9/9, prune-preview-releases 7/7, preview-feed passing (28/28 across the four files).

Not changed

  • P2 – downloads.json stays preview-only: needs a product decision (channel key / separate stable file vs. documenting preview-only). Happy to take either direction once decided.
  • Third copy of the preview-version regex: preview-feed.mjs keeps its own on purpose — its test copies that script alone into a temp directory, so a sibling import wouldn't resolve (see 43b3036's message). The prune script already imports the shared pattern.

downloads.json now follows the stable feed instead of previews, so the
website offers the release installed stable apps receive. The approved
stable feed promotion publishes it after the feed is read back; preview
promotion no longer touches it. Stable releases are never pruned, so
preview cleanup no longer needs to protect the advertised version and
returns to main's behavior.

Co-authored-by: ART <ea39c1c8acf57180161ef4ba4ed68abf8589f5291956b909a5aa991fc66664ca@buzz.block.builderlab.xyz>
Signed-off-by: Bradley Axen <baxen@squareup.com>
@matt2e
matt2e merged commit 409b6fa into main Nov 10, 2026
46 checks passed
@matt2e
matt2e deleted the tho/buzz-release-download-manifest branch November 10, 2026 06:12
damienrj added a commit that referenced this pull request Nov 10, 2026
…rminal-font-picker

* 'main' of https://github.com/block/buzz-app: (168 commits)
  Unify Membership sharing and live roster updates (#3147)
  fix(activity): show one working cue per agent request (#3166)
  Introduce opt-in first-agent setup (#2804)
  fix(codex): drop the security-review sign-in prompt from harness defaults (#3188)
  feat(releases): publish desktop download manifest (#3154)
  fix(mcp): preserve current attachments across edits (#2937)
  fix(agents): call the Claude and Codex first-run download "the integration" (#3165)
  chore(goose): bump bundled goose-acp to v1.58.1 (#3161)
  Revert "ci: use larger GitHub runners for Rust and browser journeys (#3090)" (#3180)
  Show Goose's unset thinking level as Default, not Off (#3124)
  ci(release): publish stable and beta desktop releases from v tags (#3150)
  fix(messages): end the New messages hold when no repair can sample (#3169)
  fix(search): make Command F search the Bestie conversation (#3084)
  fix(plugins): keep failed update checks on the plugin's Settings row instead of a toast (#3088)
  Show single-agent Stop on the activity bubble (#3140)
  fix: support explicit hosted browser origins (#3149)
  fix: keep Codex tool namespace descriptions bounded (#3128)
  fix(messages): show "New messages" in channels longer than one page (#3071)
  Keep shared agent guidance generic (#3134)
  fix(typing): a thread reply also ends the agent's channel-level typing (#3148)
  ...

Signed-off-by: damienrj <damien@squareup.com>

# Conflicts:
#	src-tauri/Cargo.toml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants