electron-updater@7.0.0-alpha.5
Pre-releaseMajor Changes
-
Feat(updater): default
disableWebInstallertotrue#99797a0abca@mmaiettaBREAKING CHANGE:
AppUpdater.disableWebInstallernow defaults totrue. NSIS web-installer packages are no longer loaded unless you opt in, because their payload is fetched from a manifest-supplied URL that may not undergo signature verification.v27 ships a one-major-version grace period so existing deployments are not broken without warning:
- If you never set
disableWebInstaller(the default) and a web-installer update is received, the updater logs a deprecation warning and still downloads it. In v28 this becomes an error and the download is blocked (ERR_UPDATER_WEB_INSTALLER_DISABLED). - If you explicitly set
disableWebInstaller = true, the download throwsERR_UPDATER_WEB_INSTALLER_DISABLEDimmediately.
If you intentionally publish and rely on an NSIS web installer, opt back in before v28 by setting
autoUpdater.disableWebInstaller = falsein your main process. - If you never set
-
Feat(updater)!: install-on-next-launch mode, OS session-end guard, object-form
quitAndInstall, andautoInstallEventenum#100111798f6b@claudeBREAKING:
quitAndInstallnow takes a single destructured options object instead of positional booleans, so v27 migrators discover the new deferred-install flag and can never swap arguments silently. Defaults are unchanged; there is no backward-compat shim.// Before (v26) autoUpdater.quitAndInstall(true, false) // After (v27) autoUpdater.quitAndInstall({ isSilent: true, isForceRunAfter: false })
BREAKING: the
autoInstallOnAppQuitboolean is replaced by anautoInstallEvent: "manual" | "onQuit" | "onNextLaunch"enum (default"onQuit", which preserves prior behavior). There is no compat alias — a single boolean cannot express the three states.// Before (v26) autoUpdater.autoInstallOnAppQuit = false // After (v27) autoUpdater.autoInstallEvent = "manual"
Installing an update while the app quits spawns a detached installer process; when the quit is caused by the OS session ending (shutdown/reboot/log off on Windows), the OS can kill that installer mid-install and leave the app uninstalled but not re-installed (#7807). Two mitigations, both implemented in
BaseUpdaterso NSIS, AppImage, deb, rpm and pacman targets all inherit them:- Session-end guard (always on): when the OS session is ending, the on-quit install is skipped with a warning and the downloaded update stays cached for the next quit. Detection is best-effort:
powerMonitorshutdownon macOS/Linux,BrowserWindowsession-endon Windows (windowless apps cannot be covered on Windows). autoInstallEvent: "onNextLaunch"(opt-in; default is"onQuit"): any app quit persists the downloaded update as pending instead of spawning the installer. On the next launch the updater re-validates the cached installer against freshly fetched update info (checksum, code signature on Windows, and an installable-change version check — newer, or a downgrade whenallowDowngradeis set — as a loop guard) and installs it silently, restarting the app. A single quit can be deferred via the newquitAndInstall({ waitUntilNextLaunch: true })option.
The automatic install at startup is restricted to targets that install without an elevation prompt: NSIS (per-user installs) and AppImage only. deb/rpm/pacman always elevate via pkexec/sudo to install — an authentication dialog at app launch is not acceptable — so they keep the pending update and log why; per-machine NSIS installs (UAC) are skipped the same way. For those targets, call the new
installPendingUpdateIfAvailable()explicitly at a moment the app controls.autoInstallEvent: "onNextLaunch"is opt-in in v27 and is planned to become the DEFAULT in v28 to resolve this class of session-end corruption once and for all. macOS is unaffected: Squirrel.Mac natively stages downloaded updates and applies them on relaunch (there"onQuit"and"onNextLaunch"behave identically). - Session-end guard (always on): when the OS session is ending, the on-quit install is skipped with a warning and the downloaded update stays cached for the next quit. Detection is best-effort:
Minor Changes
-
Feat: add Cloudflare R2 publish provider
#9773a086ef3@kyletaylored -
Feat(nsis): self-identify install method via
resources/package-typeso nsis-web installs defaultdisableWebInstallertofalse#99797a0abca@mmaiettaNSIS installers now write a
resources/package-typemarker (nsisornsis-web) at install time, mirroring the existing Linuxpackage-typemechanism. electron-updater'sNsisUpdaterreads this marker and, fornsis-webinstalls, pre-seedsdisableWebInstaller = falseso web-installer auto-updates keep working without the app wiring the flag by hand.This is a default only: an explicit
autoUpdater.disableWebInstaller = …set by the app still wins, and a plainnsismarker leaves the secure?? truedefault (and the v27 grace-period warning) untouched. The marker is written by the installer script — the only build artifact that differs betweennsisandnsis-web(the app payload is byte-identical, since both targets share one app archive). Only go-forward installs carry the marker; existing deployments are unaffected. -
Feat(updater): add
allowUnverifiedLinuxPackagesto optionally enforce Linux package signature verification#999065f0403@mmaiettaAdds
AppUpdater.allowUnverifiedLinuxPackages. Because electron-builder does not sign Linux packages, this defaults totrue, preserving the existing behavior:.deb/.rpmauto-updates install with the package manager's signature/GPG checks bypassed where a bypass flag exists (--allow-unauthenticatedfor the apt fallback,--allow-unsigned-rpmfor zypper,--nogpgcheckfor dnf/yum).If you sign your Linux packages through your own pipeline and the target systems trust your keys, set
autoUpdater.allowUnverifiedLinuxPackages = false. What this enforces depends on the package manager used on the target system:- dpkg (the default for
.deb): no effect — dpkg performs no signature verification (a warning is logged); enforcing.debsignatures requires a debsig-verify/debsigs policy on the target system. - apt (
.debfallback):--allow-unauthenticatedis omitted. - zypper: enforced — unsigned/untrusted packages fail to install.
- dnf/yum: enforced via
--setopt=localpkg_gpgcheck=1(local package files are not GPG-checked by default). - bare rpm (fallback): cannot be enforced via the CLI (a warning is logged) — rpm verifies signatures when present but by default does not fail the install on unsigned/untrusted packages; the
rpm -Uvh ... --nodepsfallback command is unchanged (--nodepsis a dependency-resolution bypass, not a signature bypass).
The new
allowUnverifiedparameter onDebUpdater.installWithCommandRunner/RpmUpdater.installWithCommandRunneris a trailing optional argument (defaulttrue), so existing callers remain source- and runtime-compatible. - dpkg (the default for
Patch Changes
-
Fix: Reject the differential download promise instead of crashing with an uncaughtException when the multipart range response emits a network error
#100215eed26b@claude -
Fix(updater): make GitHubProvider pick the newest available release if
allowPrerelease=truebut current version is stable#98951f681e1@AbdulrhmanGoniallowPrerelease=truewith no explicit channel and a stable current version now selects the newest valid semver release in the Atom feed (skipping unrelated non-semver tags such as other packages in a monorepo) instead of blindly taking the first feed entry (#9894).- When every published release is older than the installed version, the updater now reports "update not available" gracefully (and honors
allowDowngrade) instead of throwing. allowPrerelease=falseno longer throwsERR_UPDATER_NO_PUBLISHED_VERSIONSwhen the latest release tag (from/releases/latest) is absent from GitHub's truncated Atom feed; it proceeds with the resolved tag.- Harden the release download path against path traversal: a tag containing
./..path segments is rejected withERR_UPDATER_INVALID_TAG.
-
Fix(updater): detect legacy hex
sha512manifest values strictly and deprecate them for removal in v28#999065f0403@mmaiettaThe updater previously used a fuzzy heuristic (looking for
+,/,Z, or=characters) to decide whether a manifestsha512was hex- or base64-encoded. It now uses a strict check: a value that is exactly 128 hexadecimal characters is treated as legacy hex; anything else is decoded as base64, which is what electron-builder has emitted since 19.x (2017). The two forms cannot collide — base64-encoded sha512 is always 88 characters ending in==— and a wrong pick can only fail closed with a checksum mismatch.Hex-encoded
sha512values (from pre-19.x manifests or hand-rolled manifests built from rawsha512sumoutput) remain accepted in v27 but are deprecated: support will be removed in v28. Emit base64 instead, e.g.sha512sum file.ext | cut -d' ' -f1 | xxd -r -p | base64 -w0.SHA-256 (
sha2) update checksums are unchanged here — they remain accepted in v27 under the existing v28-removal grace period.