Major Changes
-
Feat(win)!: a missing
publisherNamefails Windows update signature verification closed.#10380674e18d—electron-builder,app-builder-lib,builder-util-runtime- electron-updater: an NSIS update is rejected with
ERR_UPDATER_INVALID_SIGNATUREwhenapp-update.yml(ordev-app-update.yml/ theupdateConfigPathfile) has nopublisherName. A customverifyUpdateFileAuthenticodeSignature/verifyUpdateCodeSignatureis never called without apublisherName. The only opt-out isverifyUpdateCodeSignature: falseinapp-update.yml, which electron-builder writes forwin.verifyUpdateCodeSignature: false; verification is then skipped with one warning per updater. An app with no update config file at all (noapp-update.yml/dev-app-update.yml, e.g. one that only usessetFeedURL) is not verified: its feed is configured by the developer. - app-builder-lib: a Windows build that writes
app-update.yml(nsis,nsis-weborelectronUpdaterAwareappxwith a publish configuration of any provider, including one inferred from a GitHubrepository) fails withInvalidConfigurationErrorwhilewin.verifyUpdateCodeSignatureis enabled and nopublisherNameresolves:win.sign: false/null, no code signing certificate, orwin.sign.publisherName: null, which is not an opt-out. Sign the build, setwin.sign.publisherName(e.g.win.sign: { type: "signtool", publisherName: [...] }when signing outside electron-builder), or setwin.verifyUpdateCodeSignature: false, which writesverifyUpdateCodeSignature: false(and nopublisherName) intoapp-update.yml. ApublisherNamein thepublishconfiguration must be a distinguished name too, andverifyUpdateCodeSignaturemust not be set there. - builder-util-runtime:
PublishConfigurationhas the private, Windows-onlyverifyUpdateCodeSignaturefield. - electron-builder:
migrate-schemaprints an advisory forwin.sign: false/nullorwin.sign.publisherName: nullwithoutwin.verifyUpdateCodeSignature: false.
- electron-updater: an NSIS update is rejected with
-
Feat(win)!: require every
publisherNameentry to be a distinguished name (DN) (e.g."CN=My Company, O=My Company, C=US"). An explicitwin.sign.publisherNamewith an entry that is not a DN (e.g. a bare name) now fails the build withInvalidConfigurationErroron every signing route (signtool,hsm,pkcs11, a customsignhook,azure) before anything is signed, because electron-updater 7 never matches such an entry;publisherName: nullstill opts out. WithoutpublisherName, the build now writesCN=<common name>of the certificate toapp-update.ymlinstead of the bare Common Name, with the value quoted the way Windows quotes it in the subject electron-updater matches against, so a renewed certificate with the same CN keeps updates working (set a fuller DN explicitly for a stricter pin); the build-time checks of an explicitpublisherNameread the subject in the format Windows reports it (e.g.S=for the state).electron-builder migrate-schemaprints an advisory for an entry that is not a DN. See https://www.electron.build/docs/migration/v27-build-changes#windows-publishername-must-be-a-distinguished-name#10380674e18d—app-builder-lib -
Feat(win)!:
matchPublisherNamematches only publisher names that are a distinguished name (DN), every attribute of which must equal the signer's; a bare name never matches the signer's Common Name any more, and itsloggerparameter is removed. New exportisValidPublisherNameDntells whether a publisher name is a DN. See https://www.electron.build/docs/migration/v27-build-changes#windows-publishername-must-be-a-distinguished-name#10380674e18d—builder-util-runtime -
Feat(signing)!:
forceCodeSigningverifies signatures and fails when notarization, update-manifest signing or any signing step is skipped (also on pull-request builds), signed update manifests are read back before they are written, and the newelectron-builder verifycommand checks built output (#10429). See https://www.electron.build/docs/migration/v27-build-changes#forcecodesigning-covers-notarization-and-update-manifests#10440046f936—electron-builder,app-builder-lib,dmg-builder -
Feat(mac)!:
mac.notarize: truerequires notarization: a build without notarization credentials fails with anInvalidConfigurationError, at build start on a macOS host and when notarizing. Left unset, notarization runs when the credentials are set and is skipped with a warning otherwise. See https://www.electron.build/docs/migration/v27-build-changes#mac-notarize-true-requires-credentials#10444145b373—app-builder-lib -
Feat(publish)!:
electron-builder publish -fchecks every update manifest (latest*.yml) before it uploads anything: an unsigned manifest is refused unlessupdateManifest: false, and withupdateManifest.publicKeyset the manifest must be signed by one of those keys (another key only withallowSigningKeyOutsideTrustList, which warns). WithoutpublicKeyit warns, and fails underforceCodeSigning. See https://www.electron.build/docs/migration/v27-build-changes#signed-update-manifests-are-required#10444145b373—electron-builder,app-builder-lib -
Feat(squirrel)!:
squirrelWindows.msi: truewarns that the MSI Squirrel.Windows builds embedsSetup.exebefore electron-builder signs it, and fails underforceCodeSigning, pointing at themsitarget for a signed MSI. See https://www.electron.build/docs/migration/v27-build-changes#forcecodesigning-covers-notarization-and-update-manifests#10444145b373—app-builder-lib,electron-builder-squirrel-windows -
Refactor(win)!: remove the
escapePowerShellSingleQuotesexport, which only shipped in 10.0.0-alpha.11; the Authenticode check passes the file path to PowerShell in an environment variable (prepareAuthenticodeSignatureExec), so no path is quoted into a PowerShell script.#10453ed05bd0—builder-util-runtime
Minor Changes
-
Feat: warn on silently skipped update signature verification and validate
publisherNameagainst the signing certificate at build time#10056331afdd—app-builder-lib· updated in#10380Two guards around Windows update signature verification:
- electron-updater: when
app-update.ymlexists but contains nopublisherName, the updater used to skip signature verification (including customverifyUpdateCodeSignaturehooks) completely silently. It now logs a warning explaining that verification was skipped, how to fix it (sign the build sopublisherNameis derived automatically, or setwin.publisherNameexplicitly), and that this fail-open behavior is deprecated. Since v27 (electron-updater 7), a missingpublisherNamein an existingapp-update.ymlis a verification failure (fail-closed) instead, unless the file hasverifyUpdateCodeSignature: false. The no-app-update.ymlpath (unpackaged/dev mode) stays silent. - app-builder-lib: when
publisherNameis explicitly configured and the subject of the local code signing certificate is known, the build now fails with a clear error if none of the configured names match the certificate (same DN-subset/CN matching semantics as the updater's verifier; any one of multiple configured names matching passes, so certificate-rotation setups keep working). This catches signing with the wrong certificate at build time instead of at update time. The check is skipped whenever the actual signing certificate's subject is not genuinely known (customsignhooks, Azure Trusted Signing, PKCS#11 without an extractable certificate, x509 files without a CN), andpublisherName: nullremains a pure opt-out.
- electron-updater: when
-
Feat(updater)!: Windows update signature verification fails closed — electron-updater installs an NSIS update only when PowerShell (
Get-AuthenticodeSignature) verifies it: an update it cannot verify (PowerShell cannot be started or run, times out, or prints unreadable output) is rejected withERR_UPDATER_SIGNATURE_UNVERIFIABLE, and a Windows catalog signature is rejected as invalid unless the app opts in with the newNsisUpdater.allowCatalogSignature(defaultfalse; whentrue, a valid catalog signature is accepted with a warning only when its signer matchespublisherName). A release can allow it instead with the newwin.allowCatalogSignaturebuild option (defaultfalse), which writesallowCatalogSignature: trueinto thelatest.ymlof thensisandnsis-webtargets; electron-updater honors it only when that manifest's signature was verified against a trusted key (updateManifestPublicKey) and ignores it with a warning otherwise. The manifest signature covers it as an extraallowCatalogSignature:trueline of theEBUM1payload only when it istrue, so manifests without it canonicalize and verify exactly as before, and changing it for a published release means re-signing or republishinglatest.yml; a signed manifest with a non-booleanallowCatalogSignatureis rejected. electron-updater 7.0.0-alpha.8 to alpha.11 installs with an update key configured reject a signed manifest that sets it (ERR_UPDATER_MANIFEST_SIGNATURE_INVALID), the same way alpha.8 treats a signedfiles[].blockMapUrl.UpdateInfoAndProvidergainsmanifestSignatureVerified, andBaseUpdater.verifyInstallerSignatureOnLaunchreceives the update info the cached installer was matched against. PowerShell is started by absolute path, the installer path is passed in an environment variable, and non-ASCII output is escaped instead of setting a console encoding, so verification works under PowerShell Constrained Language Mode (fixing 7.0.0-alpha.8 to alpha.10). The build-time installer check uses the same invocation. builder-util-runtime addsprepareAuthenticodeSignatureExecandPOWERSHELL_ASCII_ESCAPE_FUNCTION. Migration: where PowerShell may be blocked (AppLocker / WDAC), assign a nativeverifyUpdateFileAuthenticodeSignaturein your first electron-updater 7 release — see https://www.electron.build/docs/migration/v27-runtime-changes#windows-update-signature-verification-fails-closed#104168366dc6—app-builder-lib,builder-util-runtime -
Feat(runtime):
HttpExecutor.addRedirectHandlersis public, so that requests made outside the executor (electron-updater's differential downloads) follow redirects with the same rules: credential headers are dropped on another origin, and the executor's redirect limit applies#104192d97c85—builder-util-runtime -
Feat(win): export
windowsPowerShellPath(), which returns the absolute path of the in-box Windows PowerShell (%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe) for runtime use such as electron-updater, and throws whenSystemRootis not a drive-absolute path.preparePowerShellExecandprepareAuthenticodeSignatureExectake an optional PowerShell path, used instead ofwindowsPowerShellPath()when given.#10453ed05bd0—builder-util-runtime
Patch Changes
- Docs(mac): say that Electron's default
Info.plistalready enablesNSAllowsArbitraryLoadsand that only an explicitfalseinextendInfoturns it off (nulldoesn't remove the key); follow-up to #10353.#10403862437f—app-builder-lib - Fix(appx): derive the AppX/MSIX
Publisherfrom the signing certificate subject in the format Windows reports it (,-separated,Sfor the state), so MakeAppx accepts a certificate whose subject has more than a CN#10380674e18d—app-builder-lib - Refactor(win): export the Windows Authenticode helpers electron-updater verifies update signatures with (
preparePowerShellExec,parseAuthenticodeSignatureOutput,matchPublisherName), moved from electron-updater so electron-builder can check signed installers with the same code#1037860e3708—builder-util-runtime· updated in#10416 - Docs: split the v27 breaking-changes page into config, build, runtime and developer pages, point the migration links in build and updater messages at the page each change moved to, and add links to the v27 messages that had none
#10421b5e144d—electron-builder,app-builder-lib,electron-publish - Start system tools by absolute path instead of looking them up on
PATH: Windows PowerShell from%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe(for Windows code signing, package-manager commands andcreate-self-signed-cert), PowerShell 7 from%ProgramFiles%\PowerShell\7\pwsh.exeon Windows and from the install location of Microsoft's package on macOS and Linux,prlctlfrom the Parallels Desktop install location, and the host Wine (toolsets.wine: "system", the default) from its fixed install locations.SystemRootandProgramFilesmust be drive-absolute paths.#10422a7f005c—electron-builder,app-builder-lib,builder-util-runtime - Electron-builder starts the host programs it uses only from an absolute path, never by looking up a name on
PATH: PowerShell, Wine, Mono (Squirrel.Windows on macOS and Linux),prlctl,productbuild,pkgbuild,codesign,hdiutil,tiffutil,sips,actool,zip,notarytool(passed to@electron/notarizeasnotarytoolPath, located with/usr/bin/xcrunby default),lzip,snapcraft,flatpakandflatpak-builder. Each comes from its default install locations or from the newtoolsets.executablesmap, whose entries arefile://URIs, or lists of them, that replace the defaults for that program. Child processes started without an explicit environment get no credential variables on Windows either, andsnapcraft uploadgets the store credentials but no other secret. The NSIS installer startstasklistandtaskkillfrom$SYSDIR(and passes the force flag in per-machine mode), the AppImage launcher runs the dialog tool it checked by its absolute path, and electron-updater on macOS starts/usr/sbin/sysctland/usr/bin/uname.#10430b98e1f2—electron-builder,app-builder-lib,builder-util,dmg-builder,electron-builder-squirrel-windows,electron-publish - Fix(runtime):
HttpExecutor.prepareRedirectUrlOptionsleaves outhost, so a redirected request goes to the redirect target even when the original request sethost(ElectronHttpExecutor sets it from aHostheader)#104192d97c85—builder-util-runtime - Fix: escaped characters in a Windows
publisherNamedistinguished name are decoded correctly. Before, a hex pair was decoded as a single Latin-1 character (Caf\C3\A9becameCaféinstead ofCafé), and a\+or\escape followed by a hex digit was read as a hex pair (Acme\+Boltlost theB), so such a publisher name never matched the signing certificate and electron-updater rejected the update#104346393d7a—builder-util-runtime - Fix:
${env.NAME}macros now expand when the variable name contains a digit, such as${env.S3_BUCKET}. Before, the macro was left in the value as is, for example inartifactName,directories.outputor a publish configuration, and an undefined variable with a digit in its name did not raise ERR_ELECTRON_BUILDER_ENV_NOT_DEFINED#10435b086ae7—app-builder-lib - Fix(squirrel): wait for the zip/7z archive of the same app directory (whatever its arch) to finish before Squirrel.Windows writes its execution stub and re-signs the app exe in it
#104329cc8cd6—app-builder-lib,electron-builder-squirrel-windows - Fix(linux): deb/rpm/pacman write
app-update.yml,package-typeandapparmor-profileinto the app directory they package (another arch's withlinux.defaultArchset before), after waiting for the tar.*/zip/7z archive of that directory, so those archives never pick up the files halfway#104374329ef6—app-builder-lib - Fix(squirrel): copy Squirrel.exe into the app directory in
build(), with the execution stub, instead of from the queued installer work, so NSIS/AppX/MSIX never read the app directory while it is being written#10436f0dd663—electron-builder-squirrel-windows - Fix(linux): AppImage only writes
app-update.ymlitself for a prepackaged app (afterPack already wrote the same file otherwise), and then first waits for the tar.*/zip/7z archive of that app directory, so those archives never pick up the file halfway#10439169c5bb—app-builder-lib - Fix: secrets in logs and error messages (passwords, tokens and keys in redacted command lines, environments and request options) are shown as a fingerprint keyed with a random secret of the process, derived with scrypt: the same value has the same fingerprint within a run, but a fingerprint cannot be checked against guessed values offline. A value whose fingerprint cannot be computed is shown as
<redacted>.#10441955cd00—builder-util,builder-util-runtime,electron-publish - Fix: electron-builder starts
codesign,stapler,pkgutiland Windows PowerShell by absolute path, fromtoolsets.executablesor their default locations, for the signature checks offorceCodeSigningandelectron-builder verify, for re-signing the Electron framework after embedding the ASAR integrity digest and for reading the Team ID of nested binaries; the keychain it creates trusts the configuredcodesignandproductbuild. Newtoolsets.executableskeys:stapler(located with/usr/bin/xcrun --find staplerby default) andpkgutil(/usr/sbin/pkgutilby default). The signature checks passmac.sign.strictVerifytocodesign --verifyastrue,falseor a comma-separated list of the--strictkeywordsall,symlinksandsideband; another value is a configuration error. Reading an Authenticode signature back starts PowerShell without the build's credential variables.electron-builder verifyuses public keys only: without a packaged app's trust list it verifies update manifests againstupdateManifest.publicKey, and reports them as unverifiable when that is not set; it never loads a signing key. It honorsmas.sign/masDev.signopt-outs for Mac App Store apps, reads only the app output directories of the targets, and reads an app'sapp-update.ymlonly as a file inside the app, reporting one that is a symlink out of the app, invalid YAML or not a mapping as a failed check. The Team ID of a signing identity name is parsed in linear time.#10440046f936—electron-builder,app-builder-lib,builder-util - Fix(nsis): treat PowerShell as available for the running-app check only when its capability probe returns the sentinel exit code 37, so Wine's (and CrossOver's)
powershell.exestub, which runs nothing and exits with 0, falls back totasklistinstead of reporting the app as running and looping on the "cannot be closed" dialog#104420fa7237—app-builder-lib - Fix: Fall back to Latin-1 when a hex escape in a distinguished name is not valid UTF-8
#104465028cb3—builder-util-runtime - Fix(mac): a custom
mac.signsigner is called also when no keychain identity is found (with no identity, and a log line saying so); for a MAS app, whose installer needs a keychain identity, it is skipped with a warning unlessforceCodeSigningis set. Andmas.forceCodeSigning/masDev.forceCodeSigningapply to themas/mas-devtargets, cascading overmaclike every other option.#10444145b373—app-builder-lib - Fix(win): build-time Windows PowerShell, including the signature read-back of
forceCodeSigningand thepublisherNamecheck, is always resolved throughtoolsets.executables(default: the in-box Windows PowerShell underSystemRoot), so a configuredtoolsets.executables.powershellis used without readingSystemRoot.#10453ed05bd0—app-builder-lib,builder-util
Full Changelog: https://github.com/electron-userland/electron-builder/compare/electron-builder@27.0.0-alpha.12...electron-builder@27.0.0-alpha.13