refactor: build via electron-builder's programmatic API instead of the CLI#647
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Refactors the Electron build wrapper to invoke electron-builder via its programmatic build() API (instead of spawning the CLI with shell: true), eliminating shell tokenization/quoting issues and enabling structured config overrides.
Changes:
- Replaces
spawnSync('electron-builder', …, {shell: true})with an in-processelectron-builder.build(options)call. - Passes build targets as arrays and supplies config overrides via an object (including
publish: 'never'and Azure signing options when enabled). - Updates signing behavior to strip/restore CSC-related variables from
process.envduring unsigned/AppX passes, and makes the wrapper execution async/serial.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
399c957 to
e474b1c
Compare
…e CLI The wrapper spawned `electron-builder` through `spawnSync(shell: true)`, which re-tokenizes the command line — so every config value containing a space (the azureSignOptions publisherName, the appx `CN=` publisher) had to be manually double-quoted to survive shell splitting, and Node warns about the unescaped concatenation (DEP0190). Call the documented `build()` API directly instead. Options are passed as a structured object that electron-builder deep-merges over electron-builder.yaml, so there is no shell and no quoting to get wrong. Target lists go under the platform key (win/mac/linux) rather than as a `targets` Map, so electron-builder's own option normalization still parses the `type:arch` suffixes and applies the dir/universal/identity handling instead of us reimplementing it. Because the build now runs in-process, CSC stripping removes the vars from process.env (which electron-builder reads directly) for the duration of the build and restores them after. Target descriptors hold real arrays instead of space-joined strings that had to be re-split. Set `publish: 'never'` explicitly. electron-builder.yaml configures no publish providers and releases are collected from the build artifacts by hand, but electron-builder still inferred a publish policy from CI detection and warned that the implicit behavior will be dropped in a future major.
e474b1c to
b73675b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves
Addresses an issue raised in review of #635 regarding the use of
shell: true.Proposed Changes
Replaces the
spawnSync('electron-builder', ..., { shell: true })invocation inscripts/electron-builder-wrapper.jswith a direct call to electron-builder's documented programmaticbuild()API. Build options are passed as a structured object that electron-builder deep-merges overelectron-builder.yaml, instead of shell-quoted--c.x.y=valueCLI flags.Also in this change:
win/mac/linux), not as atargetsMap, soelectron-builder's own option normalization still parses the
type:archsuffixes and applies thedir/universal/identity handling. Passing a
targetsMap would short-circuit that and force us toreimplement it.
process.envfor theduration of the build and restores them after, rather than handing a child process a filtered env.
publish: 'never'explicitly.Reason for Changes
shell: truere-tokenizes the command line, so every config value containing a space (theazureSignOptionspublisherName, the appxCN=publisher) had to be manually double-quoted to surviveshell splitting, and Node warns about the unescaped concatenation (DEP0190). Passing options as a
structured object removes the shell and the quoting entirely.
publish: 'never'is set because we configure no publish providers and collect releases from the buildartifacts by hand, but electron-builder was inferring a publish policy from CI detection and warning
that the implicit behavior will be dropped in a future major.
Test Coverage
The build wrapper has no automated tests;
npm run test:lintis the repo's only check. Validated by:npm run test:lint(0 errors) andnode --check.ci.ymlon push exercises the unsigned path: macOS dmg and Windows nsis-x64 through the new API.installerspass plusazureSignOptions,and the appx pass), which runs only in
release-candidate.yml(workflow_dispatch, Azurecredentials). A release-candidate dispatch is recommended before merge.