Skip to content

feat(auto-updater): manual DMG download flow for macOS - #93

Merged
mchl7852 merged 7 commits into
mainfrom
feat/mac-manual-update-download
Aug 10, 2026
Merged

feat(auto-updater): manual DMG download flow for macOS#93
mchl7852 merged 7 commits into
mainfrom
feat/mac-manual-update-download

Conversation

@alpha5611331

Copy link
Copy Markdown
Member

Closes #92

Summary

  • Squirrel.Mac (electron-updater's mac apply mechanism) requires a real Developer ID signature, and this build only ad-hoc signs (mac.identity: "-", notarize: false in package.json - deliberate for now, see macOS auto-update doesn't apply (unsigned/ad-hoc build blocks Squirrel.Mac) #92). So the existing electron-updater flow can check for updates on macOS but can't apply them.
  • On darwin, checkForUpdates now hits the GitHub releases API directly, downloads the arch-matched .dmg, and quitAndInstall quits the app and opens the mounted DMG so the user can drag it into Applications themselves. Windows/linux keep the existing electron-updater/NSIS flow untouched.
  • mac.artifactName is now pinned to ${productName}-${version}-${arch}.${ext} so every release asset unambiguously carries its arch (needed for matching, takes effect from the next published release onward).
  • Host platform is exposed to the renderer via preload (static value, no IPC) so the "Update Downloaded" toast can show mac-appropriate copy ("Open Installer" instead of "Restart Now").

Test plan

  • pnpm lint
  • pnpm build (tsc -b + vite build)
  • pnpm run electron:build-main
  • pnpm test:main - all existing checks plus new mac-update-util suite pass
  • Real macOS device/CI verification of the darwin branch (shell.openPath, DMG mount, quit) - this was developed on Windows, so only static review + the pure-function unit tests (isNewerVersion, pickMacAsset) exercised it. Please sanity-check on a Mac before the next release ships.

The upcoming manual-download update flow needs to match a release
asset's arch by filename, which only works if every dmg/zip
unambiguously carries its arch - not the case under electron-builder's
default naming, which omits the suffix for its "default" arch.
isNewerVersion compares two dotted version strings; pickMacAsset picks
the release asset matching the running arch. Both are Electron-free so
they're unit-testable directly, without the electron stub the rest of
test/*.test.mjs needs.
Squirrel.Mac (electron-updater's mac apply mechanism) requires the app
to be signed with a real Developer ID certificate. This build only
ad-hoc signs (package.json mac.identity), so the existing
electron-updater-driven flow can check for updates on macOS but can't
apply them - see #92.

On darwin, checkForUpdates now hits the GitHub releases API directly,
downloads the arch-matched .dmg with progress reported the same way as
the existing electron-updater download-progress events, and
quitAndInstall quits the app and opens the mounted DMG so the user can
drag it into Applications themselves. Windows/linux keep the existing
electron-updater/NSIS path untouched.
Static value read at preload time, not an IPC round-trip. Needed by
the update-notification toast to show mac-appropriate install copy.
There's no silent relaunch on macOS - the downloaded toast now tells
mac users to open the installer and drag it into Applications, instead
of the Windows "Restart Now" copy that doesn't apply there.
Comment thread src/main/services/auto-updater.service.ts Outdated
Comment thread src/main/services/auto-updater.service.ts
Comment thread src/main/utils/mac-update.util.ts
gitar-bot and others added 2 commits August 10, 2026 16:44
…ix version comparison for pre-release tags

Co-authored-by: alpha <156915037+alpha5611331@users.noreply.github.com>
…rough

Adds coverage for the semver pre-release precedence and the
GitHub-provided digest field that Gitar's review fix (9c9e8d3) added to
isNewerVersion and pickMacAsset - the original tests only covered plain
integer versions and didn't touch either.

@chmm195 chmm195 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me.

@anton-karlovskiy anton-karlovskiy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

chmm195

This comment was marked as resolved.

@alpha5611331

Copy link
Copy Markdown
Member Author

@gitar-bot
Is the PR ready to merge now?

@gitar-bot

gitar-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

@gitar-bot
Is the PR ready to merge now?

Yes — the three findings raised earlier (DMG integrity verification, pre-release version parsing, and stale download cleanup) are all fixed in 9c9e8d3, with tests added in 5b479a5. The PR is approved and lint/type-check/tests are passing, so it should be good to merge.

@mchl7852 mchl7852 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice work!

@gitar-bot

gitar-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 3 resolved / 3 findings

Adds a manual DMG download and installation flow for macOS to bypass ad-hoc signing limitations, addressing previous issues with temp file cleanup, DMG integrity verification, and pre-release version handling. No open issues remain.

✅ 3 resolved
Edge Case: Downloaded DMGs accumulate in temp and are never cleaned up

📄 src/main/services/auto-updater.service.ts:206-209 📄 src/main/services/auto-updater.service.ts:239-248
Each successful mac update writes ${productName}-${version}-${arch}.dmg into a persistent temp subdirectory and it is never removed after install (only removed on download failure). Over successive updates this leaves stale multi-hundred-MB DMGs on disk. Consider clearing destDir (e.g. rm(destDir, { recursive: true, force: true })) before downloading, so only the current installer is kept.

Security: Downloaded DMG is opened without any integrity verification

📄 src/main/services/auto-updater.service.ts:202-216 📄 src/main/services/auto-updater.service.ts:251-259
The manual mac flow downloads the DMG over HTTPS and opens it via shell.openPath with no checksum or signature check, unlike electron-updater's normal verified apply path. Since the app is only ad-hoc signed, a tampered/corrupt download would be handed to the user unnoticed. Consider validating the asset against the release's published SHA (e.g. the .blockmap/latest-mac.yml sha512) before opening.

Edge Case: isNewerVersion mishandles pre-release/non-numeric version tags

📄 src/main/utils/mac-update.util.ts:4-18
split('.').map(Number) yields NaN for any segment containing a pre-release or build suffix (e.g. 1.7.0-beta.1), and every comparison against NaN is false, so such a remote version is reported as "not newer". /releases/latest normally excludes pre-releases so impact is limited, but if a tag ever carries a suffix the update is silently skipped. Consider stripping/handling non-numeric suffixes explicitly.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@mchl7852
mchl7852 merged commit ca15a34 into main Aug 10, 2026
2 checks passed
@mchl7852
mchl7852 deleted the feat/mac-manual-update-download branch August 10, 2026 17:31
@mchl7852
mchl7852 requested a review from kevinkamto August 10, 2026 20:44
@kevinkamto

Copy link
Copy Markdown
Collaborator

Good job 👍

@kevinkamto kevinkamto left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

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.

macOS auto-update doesn't apply (unsigned/ad-hoc build blocks Squirrel.Mac)

6 participants