Skip to content

Commit 906ffb1

Browse files
authoredNov 13, 2023
feat: allow api key and keychain for mac notarization (#7861)
1 parent 9883ab6 commit 906ffb1

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed
 

‎.changeset/poor-lobsters-report.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"app-builder-lib": minor
3+
---
4+
5+
feat: allow api key and keychain to be provided for mac notarization

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

+55-22
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { isMacOsHighSierra } from "./util/macosVersion"
2121
import { getTemplatePath } from "./util/pathManager"
2222
import * as fs from "fs/promises"
2323
import { notarize, NotarizeOptions } from "@electron/notarize"
24-
import { LegacyNotarizePasswordCredentials, LegacyNotarizeStartOptions, NotaryToolNotarizeAppOptions, NotaryToolStartOptions } from "@electron/notarize/lib/types"
24+
import { LegacyNotarizePasswordCredentials, LegacyNotarizeStartOptions, NotaryToolStartOptions, NotaryToolCredentials } from "@electron/notarize/lib/types"
2525

2626
export default class MacPackager extends PlatformPackager<MacConfiguration> {
2727
readonly codeSigningInfo = new Lazy<CodeSigningInfo>(() => {
@@ -487,47 +487,80 @@ export default class MacPackager extends PlatformPackager<MacConfiguration> {
487487
log.info({ reason: "`notarizeOptions` is explicitly set to false" }, "skipped macOS notarization")
488488
return
489489
}
490+
const options = this.getNotarizeOptions(appPath)
491+
if (!options) {
492+
return
493+
}
494+
await notarize(options)
495+
log.info(null, "notarization successful")
496+
}
497+
498+
private getNotarizeOptions(appPath: string) {
490499
const appleId = process.env.APPLE_ID
491500
const appleIdPassword = process.env.APPLE_APP_SPECIFIC_PASSWORD
492-
if (!appleId && !appleIdPassword) {
493-
// if no credentials provided, skip silently
494-
return
501+
502+
// option 1: app specific password
503+
if (appleId || !appleIdPassword) {
504+
if (!appleId) {
505+
throw new InvalidConfigurationError(`APPLE_ID env var needs to be set`)
506+
}
507+
if (!appleIdPassword) {
508+
throw new InvalidConfigurationError(`APPLE_APP_SPECIFIC_PASSWORD env var needs to be set`)
509+
}
510+
return this.generateNotarizeOptions(appPath, { appleId, appleIdPassword })
495511
}
496-
if (!appleId) {
497-
throw new InvalidConfigurationError(`APPLE_ID env var needs to be set`)
512+
513+
// option 2: API key
514+
const appleApiKey = process.env.APPLE_API_KEY
515+
const appleApiKeyId = process.env.APPLE_API_KEY_ID
516+
const appleApiIssuer = process.env.APPLE_API_ISSUER
517+
if (appleApiKey || appleApiKeyId || appleApiIssuer) {
518+
if (!appleApiKey || !appleApiKeyId || !appleApiIssuer) {
519+
throw new InvalidConfigurationError(`Env vars APPLE_API_KEY, APPLE_API_KEY_ID and APPLE_API_ISSUER need to be set`)
520+
}
521+
return this.generateNotarizeOptions(appPath, undefined, { appleApiKey, appleApiKeyId, appleApiIssuer })
498522
}
499-
if (!appleIdPassword) {
500-
throw new InvalidConfigurationError(`APPLE_APP_SPECIFIC_PASSWORD env var needs to be set`)
523+
524+
// option 3: keychain
525+
const keychain = process.env.APPLE_KEYCHAIN
526+
const keychainProfile = process.env.APPLE_KEYCHAIN_PROFILE
527+
if (keychain && keychainProfile) {
528+
return this.generateNotarizeOptions(appPath, undefined, { keychain, keychainProfile })
501529
}
502-
const options = this.generateNotarizeOptions(appPath, appleId, appleIdPassword)
503-
await notarize(options)
504-
log.info(null, "notarization successful")
530+
531+
// if no credentials provided, skip silently
532+
return undefined
505533
}
506534

507-
private generateNotarizeOptions(appPath: string, appleId: string, appleIdPassword: string): NotarizeOptions {
508-
const baseOptions: NotaryToolNotarizeAppOptions & LegacyNotarizePasswordCredentials = { appPath, appleId, appleIdPassword }
535+
private generateNotarizeOptions(appPath: string, legacyLogin?: LegacyNotarizePasswordCredentials, notaryToolLogin?: NotaryToolCredentials): NotarizeOptions | undefined {
509536
const options = this.platformSpecificBuildOptions.notarize
510-
if (typeof options === "boolean") {
537+
if (typeof options === "boolean" && legacyLogin) {
511538
const proj: LegacyNotarizeStartOptions = {
512-
...baseOptions,
539+
appPath,
540+
...legacyLogin,
513541
appBundleId: this.appInfo.id,
514542
}
515543
return proj
516544
}
517545
const { teamId } = options as NotarizeNotaryOptions
518-
if (teamId) {
546+
if (teamId && (legacyLogin || notaryToolLogin)) {
519547
const proj: NotaryToolStartOptions = {
520-
...baseOptions,
548+
appPath,
549+
...(legacyLogin ?? notaryToolLogin!),
521550
teamId,
522551
}
523552
return { tool: "notarytool", ...proj }
524553
}
525-
const { appBundleId, ascProvider } = options as NotarizeLegacyOptions
526-
return {
527-
...baseOptions,
528-
appBundleId: appBundleId || this.appInfo.id,
529-
ascProvider: ascProvider || undefined,
554+
if (legacyLogin) {
555+
const { appBundleId, ascProvider } = options as NotarizeLegacyOptions
556+
return {
557+
appPath,
558+
...legacyLogin,
559+
appBundleId: appBundleId || this.appInfo.id,
560+
ascProvider: ascProvider || undefined,
561+
}
530562
}
563+
return undefined
531564
}
532565
}
533566

0 commit comments

Comments
 (0)
Please sign in to comment.