feat: real in-app auto-update for the desktop app (electron-updater) - #272
feat: real in-app auto-update for the desktop app (electron-updater)#272NovakPAai wants to merge 2 commits into
Conversation
The desktop app showed an "Update Now" banner that called POST /api/update (npm i -g codbash-app@latest + restart). In the packaged Electron app that never worked: it updated an unrelated npm-global copy while the app kept running its bundled server, so the restart landed back on the old version. Replace it with a real in-place update via electron-updater: - Desktop: check GitHub Releases (latest-mac.yml/latest.yml), Download on click, progress, then Restart to relaunch onto the new version. autoDownload=false so the user controls the download; allowDowngrade/allowPrerelease pinned false. - Add mac `zip` target (Squirrel.Mac can't apply a DMG) and a Windows `nsis` target; document the zip/blockmap publish flow in RELEASE.md. - The npm-CLI self-update path is unchanged; the server refuses /api/update with 400 when CODBASH_DESKTOP=1 (set by desktop/main.js) so it can't half-update. Hardening (from security review): - will-navigate guard pins the window to the local server origin, so the powerful updater IPC bridge can't be reached by an off-origin page. - Main-process validates state before download/install (renderer buttons are UX, not the security boundary) and validates the IPC sender frame. Correctness (from code review): - Event listeners attach at autoUpdater creation so no check result is lost to a boot race; a single initial check (renderer-triggered, reload-safe). - Periodic 6h re-check skips while downloading/downloaded so it can't wipe the "ready to restart" banner. - Error state offers Check-again + Open-download-page; download is idempotent against a fast double-click. Test: test/desktop-update-guard.test.js asserts /api/update → 400 in desktop mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@vakovalskii — assigned you as reviewer/maintainer. Two things to flag. 1. Needs testing on a Windows machine 🪟I don't have Windows, so the NSIS target and the Windows auto-update path are wired up but not verified on a real Windows box. Please validate on your side (or with the other participant who has Windows):
2. This must ship in EVERY future build 🔁The mechanism now lives in the codebase (
This is the one step that's easy to forget in a manual release — step-by-step commands are in Rollout noteAuto-update only "activates" from the next release onward: the currently-installed 7.15.0 bundle doesn't ship electron-updater yet, so 7.15.0 → next still takes the old path, and next → the one after will update in place. |
|
Cross-link: this overlaps with #271 (@indapublic's desktop OTA PoC), which targets the same problem. This PR is broader — it adds the Windows NSIS target, the macOS Worth borrowing from #271: its |
Adds desktop/scripts/regenerate-latest-mac.js (+ `npm run refresh-update-feed`) so the release runbook no longer hand-edits latest-mac.yml. Generalises the idea from #271 (thanks @indapublic) to the zip+dmg feed: it parses electron-builder's own latest-mac.yml and refreshes sha512/size/blockMapSize only for entries whose bytes changed on disk (sha512 mismatch), then re-syncs the top-level sha512 to the `path` file. Schema-preserving and idempotent — the untouched .zip entries (the actual mac update artifact) are left as-is; only stapled DMG entries are recomputed. RELEASE.md step 2b now calls the script instead of the manual yaml edit. Pure transforms covered by test/desktop-update-feed.test.js. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Folded in the feed-automation idea from #271: added |
Problem
The desktop app (macOS DMG) offered an Update Now banner that hit
POST /api/update→npm i -g codbash-app@latest+ restart. In the packaged Electron app this never worked: it updated an unrelated npm-global copy while the app kept running its bundled server, so after the "restart" the app opened on the old version again. This is the exact symptom users reported ("download, click Update, it restarts, still old version").What this does
Replaces the broken web self-update with a real in-place update via
electron-updater, keeping the npm-CLI path intact.Update flow (desktop): check GitHub Releases → banner shows vX available → Download (click) → progress % → Restart to update → app relaunches onto the new version.
autoDownload=falseso the user controls the download;allowDowngrade/allowPrereleasepinnedfalse.Build/publish:
ziptarget (Squirrel.Mac installs from the zip, not the DMG) and a Windowsnsistarget.RELEASE.mddocuments publishing the zips + blockmaps +latest-mac.yml(and the Windowslatest.yml).Guard:
desktop/main.jssetsCODBASH_DESKTOP=1; the server refusesPOST /api/updatewith 400 in that mode, so nothing half-updates. The npm-CLI (codbash run) self-update path is unchanged.Security hardening (from security review)
will-navigateguard pins the window tohttp://127.0.0.1:<port>/, so the powerful updater IPC bridge can't be reached by an off-origin page (C1).textContentonly (no HTML injection).Correctness (from code review)
autoUpdatercreation → no check result lost to a boot race; single initial check (renderer-triggered, reload-safe).downloading/downloaded→ can't wipe the "ready to restart" banner.Tests
test/desktop-update-guard.test.js— spawns the server withCODBASH_DESKTOP=1, assertsPOST /api/update→ 400.electron-builder --dirconfirmselectron-updateris bundled intoapp.asar; desktop smoke (SMOKE OK) passes.Deferred (documented)
RELEASE.mdsays: keep Windows on the notify-only fallback until signed.renderDesktopUpdateState— the function is DOM-coupled and not module-exported; repo has no jsdom. The critical server guard is covered.Rollout note
🤖 Generated with Claude Code