diff --git a/package.json b/package.json index 37608dbb8e10..971eee9b31de 100644 --- a/package.json +++ b/package.json @@ -411,6 +411,7 @@ "beforeBuild": "scripts/install-cross-deps.js", "afterPack": "ts/scripts/after-pack.js", "afterSign": "ts/scripts/after-sign.js", + "afterAllArtifactBuild": "ts/scripts/after-all-artifact-build.js", "asarUnpack": [ "node_modules/better-sqlite3/build/Release/better_sqlite3.node" ], diff --git a/ts/scripts/after-all-artifact-build.ts b/ts/scripts/after-all-artifact-build.ts new file mode 100644 index 000000000000..565ed1f1822d --- /dev/null +++ b/ts/scripts/after-all-artifact-build.ts @@ -0,0 +1,12 @@ +// Copyright 2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { BuildResult } from 'electron-builder'; +import { afterAllArtifactBuild as stapleNotarization } from './staple-notarization'; + +export async function afterAllArtifactBuild( + result: BuildResult +): Promise> { + await stapleNotarization(result); + return []; +} diff --git a/ts/scripts/notarize.ts b/ts/scripts/notarize.ts index 8c4c8f8c42ef..d441a4533e17 100644 --- a/ts/scripts/notarize.ts +++ b/ts/scripts/notarize.ts @@ -52,7 +52,6 @@ export async function afterSign({ console.log(` username: ${appleId}`); console.log(` file: ${appPath}`); - // eslint-disable-next-line no-await-in-loop await notarize({ appBundleId, appPath, diff --git a/ts/scripts/staple-notarization.ts b/ts/scripts/staple-notarization.ts new file mode 100644 index 000000000000..0d100aa1a115 --- /dev/null +++ b/ts/scripts/staple-notarization.ts @@ -0,0 +1,63 @@ +// Copyright 2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { BuildResult } from 'electron-builder'; + +import { stapleApp } from 'electron-notarize'; + +import * as packageJson from '../../package.json'; + +/* eslint-disable no-console */ + +export async function afterAllArtifactBuild({ + platformToTargets, + artifactPaths, +}: BuildResult): Promise { + const platforms = Array.from(platformToTargets.keys()).map( + platform => platform.name + ); + if (platforms.length !== 1) { + console.log(`notarize: Skipping, too many platforms ${platforms}`); + return; + } + + if (platforms[0] !== 'mac') { + console.log(`notarize: Skipping, platform is ${platforms[0]}`); + return; + } + + const appBundleId = packageJson.build.appId; + if (!appBundleId) { + throw new Error( + 'appBundleId must be provided in package.json: build.appId' + ); + } + + const appleId = process.env.APPLE_USERNAME; + if (!appleId) { + console.warn( + 'appleId must be provided in environment variable APPLE_USERNAME' + ); + return; + } + + const appleIdPassword = process.env.APPLE_PASSWORD; + if (!appleIdPassword) { + console.warn( + 'appleIdPassword must be provided in environment variable APPLE_PASSWORD' + ); + return; + } + + const artifactsToStaple = artifactPaths.filter(artifactPath => + /\.(zip|dmg)$/.test(artifactPath) + ); + + for (const artifactPath of artifactsToStaple) { + console.log(`Stapling notariation for: ${artifactPath}`); + // eslint-disable-next-line no-await-in-loop + await stapleApp({ + appPath: artifactPath, + }); + } +}