feat: add beta release channel and split macOS arch builds#390
Conversation
…flow GITHUB_TOKEN events don't trigger downstream workflows. Using the App token ensures the release:published event triggers release.yml to build CLI and desktop artifacts.
Electron-builder does not generate latest*.yml auto-update manifests for pre-release versions. The deploy-update-metadata job now only runs for stable releases, preventing failures when no metadata artifacts exist.
- Split macOS desktop builds from universal into separate arm64 and x64 builds for faster CI and smaller download sizes - Add release channel (stable/beta) support to desktop auto-updater with persistence and UI toggle in Settings - Add --channel flag to CLI self-update command for opting into pre-releases - Deploy electron update metadata for both stable and beta channels - Add merge script for combining macOS metadata from separate arch builds
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughThis PR implements multi-channel update support (stable and beta) for the desktop application while simultaneously refactoring the build system to produce separate architecture-specific macOS binaries instead of universal ones. The changes flow from library-level channel support through CLI and desktop integration, culminating in a new Settings UI for channel selection, alongside a coordinated build infrastructure update with metadata merging. ChangesMulti-Channel Release Support
Multi-Architecture Build and Release
Sequence DiagramsequenceDiagram
participant User as User (Desktop App)
participant Settings as SettingsPage.svelte
participant IPC as Main IPC Handler
participant Updater as updater.ts
participant ElectronUpdater as electron-updater
User->>Settings: Click release channel (Beta)
Settings->>IPC: invoke('set_release_channel', 'beta')
IPC->>Updater: setReleaseChannel('beta')
Updater->>Updater: Save to userData/settings.json
Updater->>ElectronUpdater: Configure with channel='beta', allowPrerelease=true
Updater->>ElectronUpdater: checkForUpdates()
ElectronUpdater-->>Updater: Prerelease updates available
Updater-->>IPC: Update event
IPC-->>Settings: Success toast
Settings-->>User: Channel updated to Beta
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The PR spans multiple subsystems (library, CLI, desktop backend, renderer UI, build workflow) with moderate logic density. The core changes are well-contained within their layers: channel option refactoring is straightforward, IPC wiring is standard, and the build matrix refactor is mechanical but requires attention to condition changes. The metadata merging script adds complexity in the release workflow. Review effort is moderate due to the breadth of files and the need to verify cross-layer consistency (library → CLI → desktop → UI), but individual changes are not intricate. Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/create-release.yml:
- Around line 16-20: Replace the mutable tag actions/create-github-app-token@v3
used in the step with a full commit SHA to pin the exact action version; update
the step with id "app-token" (the block that supplies app-id and private-key
inputs) to reference actions/create-github-app-token@<full-commit-sha> (use the
commit SHA from the action's release tag) so the release workflow's
authentication step is immutable and provenance is preserved.
In @.github/workflows/release.yml:
- Line 232: The checkout step currently uses actions/checkout@v6 without
disabling credential persistence; update the actions/checkout call to set
persist-credentials: false (add a with: block containing persist-credentials:
false) so the deploy metadata checkout does not retain GH token credentials
during the job; target the checkout invocation that references
actions/checkout@v6 to make this change.
- Around line 232-235: Replace the floating action tags with full commit SHAs
for supply-chain pinning: locate the two steps using "uses: actions/checkout@v6"
and "uses: actions/download-artifact@v8" (the checkout step and the "download
update metadata artifacts" step) and change each to the corresponding
repository@<full-commit-sha> form (e.g., actions/checkout@<sha> and
actions/download-artifact@<sha>), fetching the latest trusted commit SHAs from
the official action repos and updating the workflow YAML accordingly so the
actions are pinned to immutable commit SHAs.
In `@cmd/self_update.go`:
- Around line 26-31: Validate the provided channel string and reject unknown
values instead of silently treating them as stable: check cmd.Channel against
the allowed values (e.g., "stable" and "beta") before building
selfupdate.Options, return an error (or exit) when the value is unrecognized
(typo like "bata") and only set IncludePrerelease = true when cmd.Channel ==
"beta"; apply the same validation in the other place that constructs
selfupdate.Options/sets IncludePrerelease so both occurrences enforce valid
channels and surface a clear error message.
In `@desktop/src/main/ipc.ts`:
- Around line 670-676: Validate the IPC payload before casting in the
"set_release_channel" handler: ensure args.channel is one of the allowed
ReleaseChannel values (e.g., check against the ReleaseChannel enum or permitted
string set) and reject/throw or return an error if not; only then call
setReleaseChannel(channel) and await checkForUpdatesWithChannel(channel). Update
the ipcMain.handle("set_release_channel", ...) logic to perform this guard and
avoid the unchecked cast to ReleaseChannel.
In `@desktop/src/renderer/src/pages/SettingsPage.svelte`:
- Around line 148-155: handleChannelChange currently sets the UI state
optimistically by assigning releaseChannel = channel before persisting with
setReleaseChannelIpc; when persistence fails the UI is never reverted. Save the
previous value (e.g., const prev = releaseChannel) before assigning, call await
setReleaseChannelIpc(channel) as you do, and in the catch restore releaseChannel
= prev and keep the error toast using extractErrorMessage(err); reference
function handleChannelChange, variable releaseChannel, and setReleaseChannelIpc
when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 926f32a8-dce3-4bd5-b5e0-cc4a05af63bd
📒 Files selected for processing (12)
.github/workflows/create-release.yml.github/workflows/release.ymlREADME.mdcmd/self_update.gocmd/self_update_test.godesktop/electron-builder.ymldesktop/src/main/ipc.tsdesktop/src/main/updater.tsdesktop/src/renderer/src/lib/ipc/commands.tsdesktop/src/renderer/src/pages/SettingsPage.sveltehack/merge-mac-metadata.pypkg/selfupdate/selfupdate.go
| - uses: actions/create-github-app-token@v3 | ||
| id: app-token | ||
| with: | ||
| app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} | ||
| private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify non-SHA action refs in create-release workflow
rg -n '^\s*-\s+uses:\s+[^@]+@v[0-9]+' .github/workflows/create-release.ymlRepository: devsy-org/devsy
Length of output: 148
Pin actions/create-github-app-token to a full commit SHA.
@v3 is mutable and weakens provenance guarantees for release-authentication logic. Use the commit SHA from the release tag instead (e.g., actions/create-github-app-token@<full-sha>) to prevent unexpected action updates during release workflows.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 16-16: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 16-16: dangerous use of GitHub App tokens (github-app): app token inherits blanket installation permissions
(github-app)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/create-release.yml around lines 16 - 20, Replace the
mutable tag actions/create-github-app-token@v3 used in the step with a full
commit SHA to pin the exact action version; update the step with id "app-token"
(the block that supplies app-id and private-key inputs) to reference
actions/create-github-app-token@<full-commit-sha> (use the commit SHA from the
action's release tag) so the release workflow's authentication step is immutable
and provenance is preserved.
| - uses: actions/checkout@v6 | ||
|
|
||
| - name: download update metadata artifacts | ||
| uses: actions/download-artifact@v8 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify non-SHA action refs in this workflow
rg -n '^\s*-\s+uses:\s+[^@]+@v[0-9]+' .github/workflows/release.ymlRepository: devsy-org/devsy
Length of output: 506
🏁 Script executed:
sed -n '230,240p' .github/workflows/release.ymlRepository: devsy-org/devsy
Length of output: 349
Pin GitHub Actions to full commit SHAs.
Using floating version tags (@v6, @v8) for actions/checkout and actions/download-artifact weakens supply-chain security guarantees and conflicts with strict pinning policy. Pin these actions to their full commit SHAs instead.
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 232-232: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 232-232: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 235-235: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 232 - 235, Replace the floating
action tags with full commit SHAs for supply-chain pinning: locate the two steps
using "uses: actions/checkout@v6" and "uses: actions/download-artifact@v8" (the
checkout step and the "download update metadata artifacts" step) and change each
to the corresponding repository@<full-commit-sha> form (e.g.,
actions/checkout@<sha> and actions/download-artifact@<sha>), fetching the latest
trusted commit SHAs from the official action repos and updating the workflow
YAML accordingly so the actions are pinned to immutable commit SHAs.
- Validate --channel flag in CLI (reject invalid values in PreRunE) - Validate IPC set_release_channel input before processing - Revert UI state on channel switch failure - Add persist-credentials: false to deploy-update-metadata checkout - Use argparse in merge-mac-metadata.py - Overhaul Updates section UI with card-based channel selector
✅ Deploy Preview for devsydev canceled.
|
Satisfies goconst linter by defining channelStable and channelBeta constants instead of repeating string literals.
- Add "Check for Updates" button in Settings version section - Stream update status events (checking/available/downloaded/error) to renderer - Display release notes when an update is available or downloaded - Add "Restart & Update" button when update is downloaded - Add installUpdate IPC handler to trigger quit-and-install from UI
Summary
--channel betaflag todevsy self-updateCLI command for opting into pre-release versionslatest*.yml, beta →beta*.yml) to Netlifyhack/merge-mac-metadata.pyto combine macOS metadata from the two separate arch buildsSummary by CodeRabbit
New Features
--channelflag to specify update channels (defaults to stable).Chores