const { execFileSync } = require('node:child_process');
const path = require('node:path');
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== 'darwin') return;
const {
APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID,
APPLE_API_KEY, APPLE_API_KEY_ID, APPLE_API_ISSUER
} = process.env;
const hasPassword = !!(APPLE_ID && APPLE_APP_SPECIFIC_PASSWORD && APPLE_TEAM_ID);
const hasApiKey = !!(APPLE_API_KEY && APPLE_API_KEY_ID && APPLE_API_ISSUER);
if (!hasPassword && !hasApiKey) {
console.log('[notarize] no APPLE_* credentials in env — skipping notarization (build stays unsigned).');
return;
}
let notarize;
try {
({ notarize } = require('@electron/notarize'));
} catch {
console.warn('[notarize] @electron/notarize not installed — run `npm install`. Skipping.');
return;
}
const appName = context.packager.appInfo.productFilename;
const appPath = path.join(appOutDir, `${appName}.app`);
const creds = hasApiKey
? { appleApiKey: APPLE_API_KEY, appleApiKeyId: APPLE_API_KEY_ID, appleApiIssuer: APPLE_API_ISSUER }
: { appleId: APPLE_ID, appleIdPassword: APPLE_APP_SPECIFIC_PASSWORD, teamId: APPLE_TEAM_ID };
console.log(`[notarize] submitting ${appName}.app to Apple via notarytool (this can take a few minutes)…`);
try {
await notarize({ tool: 'notarytool', appPath, ...creds });
console.log('[notarize] stapling ticket to the app…');
execFileSync('xcrun', ['stapler', 'staple', appPath], { stdio: 'inherit' });
console.log('[notarize] done — app is signed, notarized, and stapled.');
} catch (err) {
console.warn('[notarize] ⚠️ NOTARIZATION FAILED — shipping a signed-but-unnotarized build.');
console.warn('[notarize] Fix the APPLE_ID / APPLE_APP_SPECIFIC_PASSWORD / APPLE_TEAM_ID secrets to enable it.');
console.warn(`[notarize] notarytool said:\n${err && err.message ? err.message : err}`);
}
};