Skip to content

Commit

Permalink
feat: Make notarization with Apple ID more usable (altool is no lon…
Browse files Browse the repository at this point in the history
…ger supported) (#8159)

Previously, we supported notarizing with the legacy `altool` or the new `notarytool` API. The legacy tool has since been decommissioned.
1. Look at `APPLE_TEAM_ID` environment variable for getting the team to notarize as. Previously, when authenticating with an Apple ID, this property was used to determine whether to notarize with the old or new API. It's confusing to have the authentication split across these two places.
2. Mark legacy notarize API as deprecated and remove old validation.
  • Loading branch information
rotu committed Apr 3, 2024
1 parent 8e36be1 commit 15bffa0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 59 deletions.
7 changes: 7 additions & 0 deletions .changeset/moody-years-poke.md
@@ -0,0 +1,7 @@
---
"app-builder-lib": minor
"electron-builder": minor
---

Use `APPLE_TEAM_ID` env var when using notarizing with `APPLE_ID`.
Deprecate legacy (`altool`) notarization API.
6 changes: 3 additions & 3 deletions docs/configuration/mac.md
Expand Up @@ -110,8 +110,8 @@ The top-level [mac](configuration.md#Configuration-mac) key contains set of opti
<p>This option has no effect unless building for “universal” arch and applies only if <code>mergeASARs</code> is <code>true</code>.</p>
</li>
<li>
<p><code id="MacConfiguration-notarize">notarize</code> <a href="#NotarizeLegacyOptions">NotarizeLegacyOptions</a> | <a href="#NotarizeNotaryOptions">NotarizeNotaryOptions</a> | Boolean | “undefined” - Options to use for @electron/notarize (ref: <a href="https://github.com/electron/notarize">https://github.com/electron/notarize</a>). Supports both <code>legacy</code> and <code>notarytool</code> notarization tools. Use <code>false</code> to explicitly disable</p>
<p>Note: In order to activate the notarization step You MUST specify one of the following via environment variables: 1. <code>APPLE_API_KEY</code>, <code>APPLE_API_KEY_ID</code> and <code>APPLE_API_ISSUER</code>. 2. <code>APPLE_ID</code> and <code>APPLE_APP_SPECIFIC_PASSWORD</code> 3. <code>APPLE_KEYCHAIN</code> and <code>APPLE_KEYCHAIN_PROFILE</code></p>
<p><code id="MacConfiguration-notarize">notarize</code> <a href="#NotarizeLegacyOptions">NotarizeLegacyOptions</a> | <a href="#NotarizeNotaryOptions">NotarizeNotaryOptions</a> | Boolean | “undefined” - Options to use for @electron/notarize (ref: <a href="https://github.com/electron/notarize">https://github.com/electron/notarize</a>). Use <code>false</code> to explicitly disable</p>
<p>Note: In order to activate the notarization step You MUST specify one of the following via environment variables: 1. <code>APPLE_API_KEY</code>, <code>APPLE_API_KEY_ID</code> and <code>APPLE_API_ISSUER</code>. 2. <code>APPLE_ID</code>, <code>APPLE_APP_SPECIFIC_PASSWORD</code>, and <code>APPLE_TEAM_ID</code> 3. <code>APPLE_KEYCHAIN</code> and <code>APPLE_KEYCHAIN_PROFILE</code></p>
<p>For security reasons it is recommended to use the first option (see <a href="https://github.com/electron-userland/electron-builder/issues/7859">https://github.com/electron-userland/electron-builder/issues/7859</a>)</p>
</li>
</ul>
Expand All @@ -124,7 +124,7 @@ The top-level [mac](configuration.md#Configuration-mac) key contains set of opti
<h2 id="notarizenotaryoptions">NotarizeNotaryOptions</h2>
<p>undefined</p>
<ul>
<li><strong><code id="NotarizeNotaryOptions-teamId">teamId</code></strong> String - The team ID you want to notarize under for when using <code>notarytool</code></li>
<li tag.description=""><code id="NotarizeNotaryOptions-teamId">teamId</code> String - The team ID you want to notarize under for when using <code>notarytool</code> Deprecated:</li>
</ul>

<!-- end of generated block -->
Expand Down
3 changes: 0 additions & 3 deletions packages/app-builder-lib/scheme.json
Expand Up @@ -3687,9 +3687,6 @@
"type": "string"
}
},
"required": [
"teamId"
],
"type": "object"
},
"NsisOptions": {
Expand Down
68 changes: 18 additions & 50 deletions packages/app-builder-lib/src/macPackager.ts
Expand Up @@ -10,7 +10,7 @@ import { AppInfo } from "./appInfo"
import { CertType, CodeSigningInfo, createKeychain, findIdentity, Identity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { DIR_TARGET, Platform, Target } from "./core"
import { AfterPackContext, ElectronPlatformName } from "./index"
import { MacConfiguration, MasConfiguration, NotarizeLegacyOptions, NotarizeNotaryOptions } from "./options/macOptions"
import { MacConfiguration, MasConfiguration, NotarizeNotaryOptions } from "./options/macOptions"
import { Packager } from "./packager"
import { chooseNotNull, resolveFunction, PlatformPackager } from "./platformPackager"
import { ArchiveTarget } from "./targets/ArchiveTarget"
Expand All @@ -20,13 +20,7 @@ import { isMacOsHighSierra } from "./util/macosVersion"
import { getTemplatePath } from "./util/pathManager"
import * as fs from "fs/promises"
import { notarize, NotarizeOptions } from "@electron/notarize"
import {
LegacyNotarizePasswordCredentials,
LegacyNotarizeStartOptions,
NotaryToolStartOptions,
NotaryToolCredentials,
NotaryToolKeychainCredentials,
} from "@electron/notarize/lib/types"
import { NotaryToolKeychainCredentials } from "@electron/notarize/lib/types"

export type CustomMacSignOptions = SignOptions
export type CustomMacSign = (configuration: CustomMacSignOptions, packager: MacPackager) => Promise<void>
Expand Down Expand Up @@ -510,9 +504,18 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
log.info(null, "notarization successful")
}

private getNotarizeOptions(appPath: string) {
private getNotarizeOptions(appPath: string): NotarizeOptions | undefined {
let teamId = process.env.APPLE_TEAM_ID
const appleId = process.env.APPLE_ID
const appleIdPassword = process.env.APPLE_APP_SPECIFIC_PASSWORD
const options = this.platformSpecificBuildOptions.notarize
const tool = "notarytool"

const optionsTeamId = (options as NotarizeNotaryOptions)?.teamId
if (optionsTeamId) {
log.warn(null, "Please specify notarization Team ID in the `APPLE_TEAM_ID` env var instead of `notarize.teamId`")
teamId = optionsTeamId
}

// option 1: app specific password
if (appleId || appleIdPassword) {
Expand All @@ -522,7 +525,10 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
if (!appleIdPassword) {
throw new InvalidConfigurationError(`APPLE_APP_SPECIFIC_PASSWORD env var needs to be set`)
}
return this.generateNotarizeOptions(appPath, { appleId, appleIdPassword })
if (!teamId) {
throw new InvalidConfigurationError(`APPLE_TEAM_ID env var needs to be set`)
}
return { tool, appPath, appleId, appleIdPassword, teamId }
}

// option 2: API key
Expand All @@ -533,7 +539,7 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
if (!appleApiKey || !appleApiKeyId || !appleApiIssuer) {
throw new InvalidConfigurationError(`Env vars APPLE_API_KEY, APPLE_API_KEY_ID and APPLE_API_ISSUER need to be set`)
}
return this.generateNotarizeOptions(appPath, undefined, { appleApiKey, appleApiKeyId, appleApiIssuer })
return { tool, appPath, appleApiKey, appleApiKeyId, appleApiIssuer }
}

// option 3: keychain
Expand All @@ -544,50 +550,12 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
if (keychain) {
args = { ...args, keychain }
}
return this.generateNotarizeOptions(appPath, undefined, args)
return { tool, appPath, ...args }
}

// if no credentials provided, skip silently
return undefined
}

private generateNotarizeOptions(appPath: string, legacyLogin?: LegacyNotarizePasswordCredentials, notaryToolLogin?: NotaryToolCredentials): NotarizeOptions | undefined {
const options = this.platformSpecificBuildOptions.notarize
if (typeof options === "boolean" && legacyLogin) {
const proj: LegacyNotarizeStartOptions = {
appPath,
...legacyLogin,
appBundleId: this.appInfo.id,
}
return proj
}
const teamId = (options as NotarizeNotaryOptions)?.teamId
if ((teamId || options === true) && (legacyLogin || notaryToolLogin)) {
const proj: NotaryToolStartOptions = {
appPath,
...(legacyLogin ?? notaryToolLogin!),
teamId,
}
return { tool: "notarytool", ...proj }
}
if (legacyLogin) {
const { appBundleId, ascProvider } = options as NotarizeLegacyOptions
return {
appPath,
...legacyLogin,
appBundleId: appBundleId || this.appInfo.id,
ascProvider: ascProvider || undefined,
}
}
if (notaryToolLogin) {
return {
tool: "notarytool",
appPath,
...notaryToolLogin,
}
}
return undefined
}
}

function getCertificateTypes(isMas: boolean, isDevelopment: boolean): CertType[] {
Expand Down
8 changes: 5 additions & 3 deletions packages/app-builder-lib/src/options/macOptions.ts
Expand Up @@ -214,18 +214,19 @@ export interface MacConfiguration extends PlatformSpecificBuildOptions {

/**
* Options to use for @electron/notarize (ref: https://github.com/electron/notarize).
* Supports both `legacy` and `notarytool` notarization tools. Use `false` to explicitly disable
* Use `false` to explicitly disable
*
* Note: In order to activate the notarization step You MUST specify one of the following via environment variables:
* 1. `APPLE_API_KEY`, `APPLE_API_KEY_ID` and `APPLE_API_ISSUER`.
* 2. `APPLE_ID` and `APPLE_APP_SPECIFIC_PASSWORD`
* 2. `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, and `APPLE_TEAM_ID`
* 3. `APPLE_KEYCHAIN` and `APPLE_KEYCHAIN_PROFILE`
*
* For security reasons it is recommended to use the first option (see https://github.com/electron-userland/electron-builder/issues/7859)
*/
readonly notarize?: NotarizeLegacyOptions | NotarizeNotaryOptions | boolean | null
}

/** @deprecated */
export interface NotarizeLegacyOptions {
/**
* The app bundle identifier your Electron app is using. E.g. com.github.electron. Useful if notarization ID differs from app ID (unlikely).
Expand All @@ -242,8 +243,9 @@ export interface NotarizeLegacyOptions {
export interface NotarizeNotaryOptions {
/**
* The team ID you want to notarize under for when using `notarytool`
* @deprecated Set the `APPLE_TEAM_ID` environment variable instead
*/
readonly teamId: string
readonly teamId?: string
}

export interface DmgOptions extends TargetSpecificOptions {
Expand Down

0 comments on commit 15bffa0

Please sign in to comment.