Skip to content

fix(updater): break the auto-update restart/install loop#641

Merged
h4yfans merged 1 commit into
mainfrom
fix/updater-restart-install-loop
Jun 30, 2026
Merged

fix(updater): break the auto-update restart/install loop#641
h4yfans merged 1 commit into
mainfrom
fix/updater-restart-install-loop

Conversation

@h4yfans

@h4yfans h4yfans commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Problem

After downloading an update, clicking Restart did not relaunch the app. Instead the window flipped to the vault picker, the app stayed alive, and a second Restart click quit without installing. Reopening still offered the same update — an infinite loop, the app never updated.

Root cause

The install was routed through the generic graceful-shutdown path, which had three compounding defects (PR #570 fixed the install handoff but not these):

  1. app.exit(0) on the normal-quit branch skips the quit event, which silently disables electron-updater's autoInstallOnAppQuit (BaseUpdater.addQuitHandler hooks app.onQuit). A downloaded update could never install on a normal quit.
  2. closeVault() during shutdown broadcast isOpen:false to the renderer, flipping the UI to the vault picker mid-restart (single window resizes to picker size).
  3. The explicit performQuitAndInstall() path was kept, but combined with the above the app could end up alive on the picker with no way to recover in-session.

Fix

  • apps/desktop/src/main/index.ts: before-quit normal branch app.exit(0)app.quit() so the quit event fires and a downloaded update installs on any normal quit. The re-entrant before-quit returns early on isShuttingDown (no preventDefault), so the quit still completes.
  • apps/desktop/src/main/vault/index.ts: new beginVaultShutdown(); emitStatusChanged() stops the renderer vault:status-changed broadcast once shutdown begins, called at the start of before-quit → no more picker flip.
  • Keep the explicit performQuitAndInstall() path for signed builds.

Tests

  • New main-process tests: terminates via app.quit (not app.exit); hands off to performQuitAndInstall when an install was requested.
  • Full desktop main suite green (3286 pass / 0 fail) after rebuild:node; typecheck:node + eslint clean.

Verification note

The final Squirrel.Mac bundle swap is app.isPackaged-only and can't be unit-tested. The logic above is verifiable locally (see testing recipe); a signed build is only needed to confirm the actual on-disk swap. A broken release can only be repaired by the next release (updater bootstrap), so this lands the correct behavior going forward.

Routing the install through the graceful-shutdown path left three defects
that prevented downloaded updates from ever applying:

- before-quit ended the normal-quit branch with app.exit(0), which skips
  the `quit` event and silently disables electron-updater's
  autoInstallOnAppQuit. Use app.quit() so a downloaded update installs on
  a normal quit (re-entrant before-quit returns early on isShuttingDown,
  so the quit still completes).
- closeVault() during shutdown broadcast isOpen:false to the renderer,
  flipping the UI to the vault picker mid-restart. Gate the renderer
  status broadcast once shutdown begins via beginVaultShutdown().
- keep the explicit performQuitAndInstall() path for signed builds.

Adds main-process tests for the quit terminator (app.quit not app.exit)
and the install handoff (performQuitAndInstall when requested).
@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
memry-docs Ready Ready Preview, Comment Jun 30, 2026 4:46pm
memrynote-landing Ready Ready Preview, Comment Jun 30, 2026 4:46pm

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
apps/desktop/src/main/vault/index.ts 50.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@h4yfans h4yfans marked this pull request as ready for review June 30, 2026 19:12
@h4yfans h4yfans merged commit f3e5a5d into main Jun 30, 2026
15 of 16 checks passed
@h4yfans h4yfans deleted the fix/updater-restart-install-loop branch June 30, 2026 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant