Skip to content

Commit adf97dc

Browse files
feat(mac): Add support for a custom 'sign' function in mac/mas config (#8002)
1 parent 2773410 commit adf97dc

File tree

6 files changed

+68
-16
lines changed

6 files changed

+68
-16
lines changed

.changeset/fresh-poems-greet.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"app-builder-lib": minor
3+
"electron-builder": minor
4+
---
5+
6+
mac: Support for a custom 'sign' action

docs/configuration/mac.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ The top-level [mac](configuration.md#Configuration-mac) key contains set of opti
9292
<p><code id="MacConfiguration-signIgnore">signIgnore</code> Array&lt;String&gt; | String | “undefined” - Regex or an array of regex’s that signal skipping signing a file.</p>
9393
</li>
9494
<li>
95+
<p><code id="MacConfiguration-sign">sign</code> module:app-builder-lib/out/macPackager.__type | String | “undefined” - The custom function (or path to file or module id) to sign an app bundle.</p>
96+
</li>
97+
<li>
9598
<p><code id="MacConfiguration-timestamp">timestamp</code> String | “undefined” - Specify the URL of the timestamp authority server</p>
9699
</li>
97100
<li>

packages/app-builder-lib/scheme.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2787,6 +2787,20 @@
27872787
"string"
27882788
]
27892789
},
2790+
"sign": {
2791+
"anyOf": [
2792+
{
2793+
"typeof": "function"
2794+
},
2795+
{
2796+
"type": [
2797+
"null",
2798+
"string"
2799+
]
2800+
}
2801+
],
2802+
"description": "The custom function (or path to file or module id) to sign an app bundle."
2803+
},
27902804
"signIgnore": {
27912805
"anyOf": [
27922806
{
@@ -3420,6 +3434,20 @@
34203434
"string"
34213435
]
34223436
},
3437+
"sign": {
3438+
"anyOf": [
3439+
{
3440+
"typeof": "function"
3441+
},
3442+
{
3443+
"type": [
3444+
"null",
3445+
"string"
3446+
]
3447+
}
3448+
],
3449+
"description": "The custom function (or path to file or module id) to sign an app bundle."
3450+
},
34233451
"signIgnore": {
34243452
"anyOf": [
34253453
{

packages/app-builder-lib/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export { SnapOptions, PlugDescriptor, SlotDescriptor } from "./options/SnapOptio
3939
export { Metadata, AuthorMetadata, RepositoryInfo } from "./options/metadata"
4040
export { AppInfo } from "./appInfo"
4141
export { SquirrelWindowsOptions } from "./options/SquirrelWindowsOptions"
42+
export { CustomMacSign, CustomMacSignOptions } from "./macPackager"
4243
export {
4344
WindowsSignOptions,
4445
CustomWindowsSignTaskConfiguration,

packages/app-builder-lib/src/macPackager.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { DIR_TARGET, Platform, Target } from "./core"
1313
import { AfterPackContext, ElectronPlatformName } from "./index"
1414
import { MacConfiguration, MasConfiguration, NotarizeLegacyOptions, NotarizeNotaryOptions } from "./options/macOptions"
1515
import { Packager } from "./packager"
16-
import { chooseNotNull, PlatformPackager } from "./platformPackager"
16+
import { chooseNotNull, resolveFunction, PlatformPackager } from "./platformPackager"
1717
import { ArchiveTarget } from "./targets/ArchiveTarget"
1818
import { PkgTarget, prepareProductBuildArgs } from "./targets/pkg"
1919
import { createCommonTarget, NoOpTarget } from "./targets/targetFactory"
@@ -23,6 +23,9 @@ import * as fs from "fs/promises"
2323
import { notarize, NotarizeOptions } from "@electron/notarize"
2424
import { LegacyNotarizePasswordCredentials, LegacyNotarizeStartOptions, NotaryToolStartOptions, NotaryToolCredentials } from "@electron/notarize/lib/types"
2525

26+
export type CustomMacSignOptions = SignOptions
27+
export type CustomMacSign = (configuration: CustomMacSignOptions, packager: MacPackager) => Promise<void>
28+
2629
export default class MacPackager extends PlatformPackager<MacConfiguration> {
2730
readonly codeSigningInfo = new Lazy<CodeSigningInfo>(() => {
2831
const cscLink = this.getCscLink()
@@ -231,7 +234,7 @@ export default class MacPackager extends PlatformPackager<MacConfiguration> {
231234
}
232235
}
233236

234-
if (identity == null) {
237+
if (!options.sign && identity == null) {
235238
await reportError(isMas, certificateTypes, qualifier, keychainFile, this.forceCodeSigning)
236239
return false
237240
}
@@ -263,9 +266,9 @@ export default class MacPackager extends PlatformPackager<MacConfiguration> {
263266
return path.resolve(appPath, destination)
264267
})
265268
)
266-
log.info("Signing addtional user-defined binaries: " + JSON.stringify(binaries, null, 1))
269+
log.info({ binaries }, "signing additional user-defined binaries")
267270
}
268-
const customSignOptions = (isMas ? masOptions : this.platformSpecificBuildOptions) || this.platformSpecificBuildOptions
271+
const customSignOptions: MasConfiguration | MacConfiguration = (isMas ? masOptions : this.platformSpecificBuildOptions) || this.platformSpecificBuildOptions
269272

270273
const signOptions: SignOptions = {
271274
identityValidation: false,
@@ -306,16 +309,7 @@ export default class MacPackager extends PlatformPackager<MacConfiguration> {
306309
provisioningProfile: customSignOptions.provisioningProfile || undefined,
307310
}
308311

309-
log.info(
310-
{
311-
file: log.filePath(appPath),
312-
identityName: identity.name,
313-
identityHash: identity.hash,
314-
provisioningProfile: signOptions.provisioningProfile || "none",
315-
},
316-
"signing"
317-
)
318-
await this.doSign(signOptions)
312+
await this.doSign(signOptions, customSignOptions)
319313

320314
// https://github.com/electron-userland/electron-builder/issues/1196#issuecomment-312310209
321315
if (masOptions != null && !isDevelopment) {
@@ -393,8 +387,22 @@ export default class MacPackager extends PlatformPackager<MacConfiguration> {
393387
}
394388

395389
//noinspection JSMethodCanBeStatic
396-
protected doSign(opts: SignOptions): Promise<any> {
397-
return signAsync(opts)
390+
protected async doSign(opts: SignOptions, customSignOptions: MacConfiguration): Promise<void> {
391+
const customSign = await resolveFunction(this.appInfo.type, customSignOptions.sign, "sign")
392+
393+
const { app, platform, type, identity, provisioningProfile } = opts
394+
log.info(
395+
{
396+
file: log.filePath(app),
397+
platform,
398+
type,
399+
identity: identity || "none",
400+
provisioningProfile: provisioningProfile || "none",
401+
},
402+
customSign ? "executing custom sign" : "signing"
403+
)
404+
405+
return customSign ? Promise.resolve(customSign(opts, this)) : signAsync(opts)
398406
}
399407

400408
//noinspection JSMethodCanBeStatic

packages/app-builder-lib/src/options/macOptions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { PlatformSpecificBuildOptions, TargetConfiguration, TargetSpecificOptions } from "../index"
2+
import { CustomMacSign } from "../macPackager"
23

34
export type MacOsTargetName = "default" | "dmg" | "mas" | "mas-dev" | "pkg" | "7z" | "zip" | "tar.xz" | "tar.lz" | "tar.gz" | "tar.bz2" | "dir"
45

@@ -175,6 +176,11 @@ export interface MacConfiguration extends PlatformSpecificBuildOptions {
175176
*/
176177
readonly signIgnore?: Array<string> | string | null
177178

179+
/**
180+
* The custom function (or path to file or module id) to sign an app bundle.
181+
*/
182+
readonly sign?: CustomMacSign | string | null
183+
178184
/**
179185
* Specify the URL of the timestamp authority server
180186
*/

0 commit comments

Comments
 (0)