8000 feat: Add @electron/windows-sign by felixrieseberg · Pull Request #1609 · electron/packager · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: Add @electron/windows-sign #1609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related e 8000 mails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@electron/notarize": "^2.1.0",
"@electron/osx-sign": "^1.0.5",
"@electron/universal": "^2.0.1",
"@electron/windows-sign": "^1.0.0",
"cross-spawn-windows-exe": "^1.2.0",
"debug": "^4.0.1",
"extract-zip": "^2.0.0",
Expand Down
13 changes: 13 additions & 0 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ module.exports = {
args.asar = true
}

// windows-sign: `Object` or `true`
if (args.windowsSign === 'true') {
warning('--windows-sign does not take any arguments, it only has sub-properties (see --help)', args.quiet)
args.windowsSign = true
} else if (typeof args['windows-sign'] === 'object') {
if (Array.isArray(args['windows-sign'])) {
warning('Remove --windows-sign (the bare flag) from the command line, only specify sub-properties (see --help)', args.quiet)
} else {
// Keep kebab case of sub properties
args.windowsSign = args['windows-sign']
}
}

// osx-sign: `Object` or `true`
if (args.osxSign === 'true') {
warning('--osx-sign does not take any arguments, it only has sub-properties (see --help)', args.quiet)
Expand Down
33 changes: 25 additions & 8 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
import { CreateOptions as AsarOptions } from '@electron/asar';
import { ElectronDownloadRequestOptions as ElectronDownloadOptions } from '@electron/get';
import { NotaryToolCredentials } from '@electron/notarize/lib/types';
import { SignOptions } from '@electron/osx-sign/dist/esm/types';
import { SignOptions as OSXInternalSignOptions } from '@electron/osx-sign/dist/esm/types';
import { SignOptions as WindowsInternalSignOptions } from '@electron/windows-sign/dist/esm/types';
import type { makeUniversalApp } from '@electron/universal';

type MakeUniversalOpts = Parameters<typeof makeUniversalApp>[0]
Expand Down Expand Up @@ -108,12 +109,12 @@ declare namespace electronPackager {
* @param callback - Must be called once you have completed your actions.
*/
(
buildPath: string,
electronVersion: string,
platform: TargetArch,
arch: TargetArch,
callback: (err?: Error | null) => void
) => void;
buildPath: string,
electronVersion: string,
platform: TargetArch,
arch: TargetArch,
callback: (err?: Error | null) => void
) => void;

type TargetDefinition = {
arch: TargetArch;
Expand All @@ -122,7 +123,7 @@ declare namespace electronPackager {
type FinalizePackageTargetsHookFunction = (targets: TargetDefinition[], callback: (err?: Error | null) => void) => void;

/** See the documentation for [`@electron/osx-sign`](https://npm.im/@electron/osx-sign#opts) for details. */
type OsxSignOptions = Omit<SignOptions, 'app' | 'binaries' | 'platform' | 'version'>;
type OsxSignOptions = Omit<OSXInternalSignOptions, 'app' | 'binaries' | 'platform' | 'version'>;

/**
* See the documentation for [`@electron/universal`](https://github.com/electron/universal)
Expand All @@ -146,6 +147,14 @@ declare namespace electronPackager {
schemes: string[];
}

/**
* See the documentation for [`@electron/windows-sign`](https://github.com/electron/windows-sign)
* for details.
*/
interface WindowsSignOptions extends Omit<WindowsInternalSignOptions, 'appDirectory'> {
continueOnError?: boolean
}

/**
* A collection of application metadata to embed into the Windows executable.
*
Expand Down Expand Up @@ -487,6 +496,14 @@ declare namespace electronPackager {
*
* Defaults to the current working directory.
*/
/**
* If present, signs Windows binary files.
* When the value is `true`, pass default configuration to the signing module. See
* [@electron/windows-sign](https://npm.im/@electron/windows-sign) for sub-option descriptions and
* their defaults.
* @category Windows
*/
windowsSign?: true | WindowsSignOptions;
out?: string;
/**
* Whether to replace an already existing output directory for a given platform (`true`) or
Expand Down
37 changes: 37 additions & 0 deletions src/win32.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const debug = require('debug')('electron-packager')
const path = require('path')
const { WrapperError } = require('cross-spawn-windows-exe')
const { sign } = require('@electron/windows-sign')

const App = require('./platform')
const common = require('./common')
Expand Down Expand Up @@ -98,15 +99,51 @@ class WindowsApp extends App {
}
}

async signAppIfSpecified () {
const windowsSignOpt = this.opts.windowsSign
const windowsMetaData = this.opts.win32metadata

if (windowsSignOpt) {
const signOpts = createSignOpts(windowsSignOpt, windowsMetaData, this.renamedAppPath)
debug(`Running @electron/windows-sign with the options ${JSON.stringify(signOpts)}`)
try {
await sign(signOpts)
} catch (err) {
// Although not signed successfully, the application is packed.
if (signOpts.continueOnError) {
common.warning(`Code sign failed; please retry manually. ${err}`, this.opts.quiet)
} else {
throw err
}
}
}
}

async create () {
await this.initialize()
await this.renameElectron()
await this.copyExtraResources()
await this.runRcedit()
await this.signAppIfSpecified()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this definitely run after the afterCopy hook? Just double checking this is run after any potential mutations to the exe. E.g. via fuses

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! The only thing that happens after is moving the package to its final destination and the afterComplete hook. For future convenience, this is also exactly when we sign & notarize on macOS.

return this.move()
}
}

function createSignOpts (properties, windowsMetaData, appDirectory) {
let result = { appDirectory }

if (typeof properties === 'object') {
result = { ...properties, appDirectory }
}

// A little bit of convenience
if (windowsMetaData && windowsMetaData.FileDescription && !result.description) {
result.description = windowsMetaData.FileDescription
}

return result
}

module.exports = {
App: WindowsApp,
updateWineMissingException: updateWineMissingException
Expand Down
18 changes: 18 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ test('CLI argument: --out without a value is the same as not passing --out', t =
t.is(args.out, null)
})

test('CLI argument: --windows-sign=true', t => {
const args = cli.parseArgs(['--windows-sign=true'])
t.true(args.windowsSign)
})

test('CLI argument: --windows-sign and --windows-sign subproperties should not be mixed', t => {
util.setupConsoleWarnSpy()
cli.parseArgs(['--windows-sign', '--windows-sign.identity=identity'])
util.assertWarning(t, 'WARNING: Remove --windows-sign (the bare flag) from the command line, only specify sub-properties (see --help)')
})

test('CLI argument: --windows-sign is object', t => {
const args = cli.parseArgs([
'--windows-sign.identity=identity'
])
t.is(args.windowsSign.identity, 'identity')
})

test('CLI argument: --protocol with a corresponding --protocol-name', t => {
const args = cli.parseArgs(['--protocol=foo', '--protocol-name=Foo'])
t.deepEqual(args.protocols, [{ schemes: ['foo'], name: 'Foo' }])
Expand Down
4 changes: 4 additions & 0 deletions usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ osx-universal (macOS host platform only, requires --arch=universal) Options
e.g. --osx-universal.mergeASARs="true"
For info on supported values see
https://electron.github.io/packager/main/modules/electronpackager.html#osxuniversaloptions
windows-sign Whether to sign Windows binary files with a codesigning certificate. You can either
pass --windows-sign by itself to use the default configuration or use dot notation to configure
a list of sub-properties, e.g. --windows-sign.certificateFile="C:\cert.pfx".
For info on supported values see https://npm.im/@electron/windows-sign.
protocol URL protocol scheme to register the app as an opener of.
For example, `--protocol=myapp` would register the app to open
URLs such as `myapp://path`. This argument requires a `--protocol-name`
Expand Down
14 changes: 14 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@
minimatch "^9.0.3"
plist "^3.1.0"

"@electron/windows-sign@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@electron/windows-sign/-/windows-sign-1.0.0.tgz#f08a0a5d4b96840ab637ce11228a59ee8b665287"
integrity sha512-sdkQYAR/TQCEyYgz2jMbusL/ljdj6qA7vyIm/S9HICMAitXhXROFHUOLLgiORj1uiaf2EOB2U33DatGubUuZaQ==
dependencies:
debug "^4.3.4"
fs-extra "^11.1.1"
minimist "^1.2.8"

"@eslint/eslintrc@^0.4.3":
version "0.4.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
Expand Down Expand Up @@ -3376,6 +3385,11 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==

minimist@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==

ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
Expand Down
0