import { existsSync } from "node:fs"; import path from "node:path"; import { spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; function getCodesignArgs() { const identity = process.env.ELECTROBUN_DEVELOPER_ID || "-"; const args = ["--force", "--deep"]; if (identity !== "-") { args.push("--options", "runtime", "--timestamp"); } args.push("--sign", identity); return { identity, args }; } export function codesignMacAppBundle(appBundlePath) { if (process.platform !== "darwin") { console.log("codesign-macos-app: skipping (not macOS)"); return; } if (!appBundlePath || !existsSync(appBundlePath)) { throw new Error(`codesign-macos-app: app bundle not found: ${appBundlePath}`); } const contentsPath = path.join(appBundlePath, "Contents"); if (!existsSync(contentsPath)) { throw new Error(`codesign-macos-app: invalid app bundle: ${appBundlePath}`); } const { identity, args } = getCodesignArgs(); const result = spawnSync("codesign", [...args, appBundlePath], { stdio: "inherit", }); if (result.status !== 0) { throw new Error( `codesign failed with exit code ${result.status ?? 1}`, ); } const verify = spawnSync( "codesign", ["--verify", "--deep", "--strict", "--verbose=2", appBundlePath], { encoding: "utf8" }, ); if (verify.status !== 0) { throw new Error( `codesign verify failed: ${verify.stderr || verify.stdout || "unknown error"}`, ); } const label = identity === "-" ? "ad-hoc" : identity; console.log(`codesign-macos-app: signed ${appBundlePath} (${label})`); } function resolveAppBundlePath() { const fromEnv = process.env.ELECTROBUN_WRAPPER_BUNDLE_PATH; if (fromEnv && existsSync(fromEnv)) { return path.resolve(fromEnv); } const fromArgv = process.argv[2]; if (fromArgv && existsSync(fromArgv)) { return path.resolve(fromArgv); } return null; } const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : null; const modulePath = fileURLToPath(import.meta.url); if (invokedPath === modulePath) { const appBundlePath = resolveAppBundlePath(); if (!appBundlePath) { console.error( "codesign-macos-app: set ELECTROBUN_WRAPPER_BUNDLE_PATH or pass app bundle path", ); process.exit(1); } codesignMacAppBundle(appBundlePath); }