fix(desktop): repair macOS auto-updater (ESM autoUpdater + app_ready handler)#462
Conversation
Main runs as ESM (`"type": "module"` in desktop/package.json). Node's
cjs-module-lexer doesn't surface electron-updater's `autoUpdater` getter
(defined via Object.defineProperty on exports) as a named export, so
`const { autoUpdater } = await import("electron-updater")` was always
undefined and the unsupported-build error fired on every packaged build.
Reach the getter through `mod.default.autoUpdater` (CJS module.exports)
via a small `loadAutoUpdater()` helper, used by all three call sites.
The renderer invokes `app_ready` on mount (App.svelte) but no main-side handler existed, so the promise always rejected with "No handler registered for 'app_ready'". The error was silently swallowed until PR #459 added a console.warn surfacing it. Register the handler alongside the other update IPCs. It replays the current updater status to the renderer so a freshly-mounted (or reloaded) UI immediately reflects state main already knows.
✅ Deploy Preview for devsydev canceled.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR refactors Electron updater module loading to correctly handle ESM/CJS interop, adds an app-ready IPC handler to broadcast update status, and hardens release notes parsing for null values. The core change introduces ChangesUpdater system and IPC integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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 |
The updater now reads autoUpdater via mod.default?.autoUpdater (the CJS/ESM interop path required under "type": "module"). The test mock only defined the top-level autoUpdater export, so accessing mod.default threw a vitest strict-mock error. Make the mock mirror the real module shape.
Summary
Two independent bugs were preventing the desktop auto-updater from working on macOS in v1.10.0-beta.14 (and earlier):
autoUpdaterwas undefined under ESM.desktop/package.jsonhas"type": "module", so the main bundle runs as ESM.await import("electron-updater")against electron-updater's CJS module does not surfaceautoUpdateras a named export — it's defined viaObject.defineProperty(exports, "autoUpdater", { get }), which Node's cjs-module-lexer doesn't detect. Result:const { autoUpdater } = await import("electron-updater")was alwaysundefined, the!autoUpdaterguard inupdater.tsalways fired, and the UI showed "Update check failed: Updates require a packaged build" even on properly signed/notarized builds.Verified directly:
Fixed by introducing a small
loadAutoUpdater()helper that readsmod.default?.autoUpdater ?? mod.autoUpdater(thedefaultpath invokes the CJS getter). Used at all three call sites inupdater.ts.Prior PRs (fix(desktop): handle missing autoUpdater on unsigned macOS builds #391, feat(desktop): redesign update UX #459) misread the symptom as a code-signing limitation; the real cause is the ESM/CJS interop.
app_readyIPC handler was never registered. The renderer invokesappReady()on mount (App.svelte:111), but noipcMain.handle("app_ready", ...)existed in main. The promise rejection was silently swallowed until feat(desktop): redesign update UX #459 added aconsole.warnsurfacing it. Handler added next to the other update IPCs; it replays the current updater status so a freshly-mounted UI immediately sees state main already knows.Also widened
normalizeReleaseNotesto acceptnote: string | nullto match electron-updater's realReleaseNoteInfotype (the helper's stricter return type surfaced this).Not fixed here
https://dl.devsy.sh/desktop/latest-mac.yml404 turned out to be expected — beta releases publishbeta-mac.ymlonly (release.yml gateslatest-*on non-prerelease), andbeta-mac.ymlreturns 200 with a healthy manifest. No publishing-pipeline change needed.Verification
npx tsc --noEmitnet-improves type errors (2 updater.ts errors removed; 3 pre-existing errors incli.test.ts/analytics.tsunchanged).Summary by CodeRabbit
Bug Fixes
New Features