Repository navigation
ci(release): publish stable and beta desktop releases from v tags - #3150
Conversation
|
🤖 Review from drone00 (agent reviewer) at head Verdict: Not ready. Two small should-fix items, no blockers. The design matches what was agreed, and preview behaviour is preserved. What's solid
Should-fix
Optional
Evidence (at
|
|
🤖 Re-review from drone00 at head
No regressions in the diff since
|
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1df3b76569
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Pushing a protected vX.Y.Z or vX.Y.Z-beta.N tag now builds every desktop platform and publishes it on the Releases page: a stable tag as Latest, a beta as a prerelease. The macOS, Windows, Linux, updater-signing and publication jobs move from release.yml into the reusable desktop-build.yml, which previews and stable releases both call, so both lanes publish the same verified assets. Stable builds embed the stable-feed endpoint. Serving a stable release to installed apps stays a separate, approved dispatch (desktop-stable-feed.yml), which reuses the preview feed's signature, endpoint and rollback gate. Betas never reach that feed. Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Signed-off-by: Bradley Axen <baxen@squareup.com>
…ironment Promotion now requires a published, non-draft release: a failed publication can leave a draft whose asset URLs 404 publicly. The stable feed dispatch fails closed unless desktop-stable-feed has required reviewers and deploys only from main, since GitHub creates a missing environment without protection. Tests run the real ruleset, environment and release jq filters against fixtures. Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Signed-off-by: Bradley Axen <baxen@squareup.com>
1df3b76 to
bc174e1
Compare
The tag check accepted a matching ruleset whatever its bypass list, and GITHUB_TOKEN cannot read bypass actors. A write role or App given a bypass could then cut a stable release from any main commit. Require the tag's pusher (github.actor, kept across re-runs) to have admin permission, failing closed when it cannot be read, and reject a ruleset the workflow's own token can bypass. Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
|
🤖 drone00 re-review of
Optional, no change needed: |
This reverts commit 42f35e2. The tag ruleset is the authority on who can cut a release: its bypass list is an intentional admin choice, and requiring an admin pusher in the workflow duplicates that policy and blocks deliberate changes to it. Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 One release-policy timing concern and one regression-test gap. The timing concern is based on static tracing; hosted rerun behavior remains unverified.
Execute desktop-build.yml's release source step: previews only from main with no version, releases only from their own version's tag, and every signing secret required. Disabling the comparison, or always expecting main, now fails the suite. The stable workflow checks only that the tag ruleset is active when it runs, so the setup docs now require activating it before the workflow reaches main, while no stable or beta tags exist. Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Approved at Kalvin’s explicit direction, with the review concerns classified as nonblocking P3s. The release-authorization timing concern is downgraded from P2; the earlier hold recommendation is withdrawn.
Inspected the delta from a79cb57 to 241eed1: it adds the protection setup/audit instructions and production source-ref guard regression cases, addressing both comments. No production implementation changed in this delta. Earlier validation applies to a79cb57; I did not rerun tests for this documentation/test-only update. Native updater, hosted signing and live release validation remain unverified. This approval does not claim those checks were performed.
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>
…nt-progress-rows * origin/main: 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) Signed-off-by: Gil Birman <gil@squareup.com>
…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
What
A public stable release lane for the desktop app, in GitHub Actions only (buzz-releases and its
desktop-v*tags are unchanged).desktop-stable.ymlruns on a pushedv[0-9]*tag (preview tagsv*-preview.*are filtered out). Before building it requires:vX.Y.ZorvX.Y.Z-beta.N;refs/tags/v*;mainhistory.It then builds every platform with the tag's version, not
tauri.conf.json's. A stable tag publishes a full release marked Latest; a beta publishes a prerelease. Both use--verify-tag, so they publish on the existing tag and never create one.desktop-build.yml(new, reusable) holds the macOS aarch64/x64 sign-and-notarize, Windows, Linux, updater-signing and publication jobs moved out ofrelease.yml. Previews, Windows/Linux candidates and stable/beta releases all call it, so they publish the same twelve assets and the sameSHA256SUMS. Stable and beta builds embed the sameBUZZ_UPDATER_PUBLIC_KEYwith…/stable-feed/latest.json, and each platform's existing endpoint check now checks that endpoint.desktop-stable-feed.ymlis a manual dispatch frommain, behind thedesktop-stable-feedenvironment, that writesstable-feed/latest.jsonfor one version. It runs the preview feed's gate, which is nowscripts/promote-updater-feed.sh, shared with preview promotion: signatures, embedded endpoint/key, no rollback, read-back compare. It accepts onlyX.Y.Zand a published, non-draft, non-prerelease release, so betas never reach the stable feed. It also refuses to run unless the environment has required reviewers and deploys only frommain, because GitHub creates a missing environment without protection (needsactions: read).scripts/preview-feed.mjspicks the feed, endpoint and version format from the version itself.docs/releases.mdcovers the new lane, the feed, and the admin setup.Previews are unchanged: same versions, assets, checks, feed promotion and pruning, except that preview promotion now also refuses a draft release (the shared gate checks
isDraft). The visible differences are check names (desktop / …), the publish job's name, and the macOS version step, which now runsscripts/candidate-version.mjslike Windows/Linux instead of an inline copy. Preview pruning only matches-preview.N.Mtags, and its test now covers a beta prerelease and thestable-feedrelease as well.tauri.conf.jsonis not changed.Admin setup needed before the first tag
refs/tags/v*, excluderefs/tags/v*-preview.*, restrict creation/update/deletion, block force pushes, bypass = admin role. The workflow refuses to publish until this ruleset exists.v…-previewtags withGITHUB_TOKEN(gh release create --target), and pruning deletes them the same way.GITHUB_TOKENcan't bypass a ruleset, so a ruleset covering all ofv*would break every preview publication and cleanup. Making GitHub Actions a bypass actor would let any workflow on any branch create a stable tag.publish-desktop-release-tag.shrequires thedesktop-v*ruleset to have no exclusions.desktop-stable-feed: required reviewers, custom deployment branch policy with onlymain. Promotion fails until both are set.OSX_CODESIGN_ROLE's OIDC trust policy (see below).Not verified
Whether
GITHUB_TOKENwithactions: readcan read the environment and its branch policies. GitHub documents that permission for these endpoints, but it hasn't run. If it can't, promotion fails closed with an API error.OIDC trust for macOS signing. Tag runs present
sub: repo:block/buzz-app:ref:refs/tags/v…. If the role only trustsrefs/heads/main, stable macOS signing will fail. If it also pinsjob_workflow_reftorelease.yml, moving the job intodesktop-build.ymlwould break previews as well. I can't read the policy from here.No workflow has run yet. Previews run through the reusable workflow for the first time on the next scheduled or manual run after merge. A manual
gh workflow run release.yml --ref mainright after merging is the cheapest end-to-end check.The fnmatch exclusion behaviour (
v*-preview.*matchingv0.7.0-preview.22.1) is from GitHub's documented ruleset syntax. It hasn't been tried on this repository.Validation
node --testondesktop-release,desktop-stable(new),packaging,preview-feed,prune-preview-releasesandbuzz-cli: 32/32 pass.jqfilters against fixture responses indesktop-stable.test.mjs.--target;preview-feed;main;actionlint1.7.7 (with shellcheck) passes onrelease.yml,desktop-stable.ymlanddesktop-stable-feed.yml.desktop-build.ymlreports one SC2015 info on the Linux check that moved verbatim fromrelease.yml, andshellcheckpasses on the new script.tests/integration/*.test.mjs: 300/301 pass. The one failure isworktree-icon.test.mjs"macOS launchers preserve…", which fails on a missingscripts/dev-credential-helper.mjsin its temp checkout and doesn't touch these files.--lateststays forced for stable tags. Leaving it off doesn't help, because the API'smake_latestdefaults totruefor new non-prerelease releases. Holding Latest for an older-line hotfix would need a version comparison, and there's no older line yet.Draft until drone00 has reviewed it and a human has watched the first preview run go through the reusable workflow.