Something went wrong. Try again.
All-in-one editor for Paper Mario (N64) mods diorama64.starhaven.dev
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667// SPDX-FileCopyrightText: 2026 Alexander Bates <alex@bates64.com>//// SPDX-License-Identifier: 0BSD
// electron-builder's afterPack hook. On macOS it signs and notarizes the app// itself, but it can't elsewhere, so a macOS app packaged on another// platform is signed, notarized, and stapled here with rcodesign instead,// before electron-builder zips it for updates.//// Needs APPLE_DEVELOPER_ID_PEM (a Developer ID Application certificate and// its key, as PEM) and APPLE_NOTARY_API_KEY (an App Store Connect API key,// in the JSON form `rcodesign encode-app-store-connect-api-key` writes),// both base64-encoded. Without them the app is left unsigned.
import { spawnSync } from "node:child_process";import { mkdtemp, rm, writeFile } from "node:fs/promises";import { tmpdir } from "node:os";import { dirname, join } from "node:path";import { fileURLToPath } from "node:url";import { Arch } from "builder-util";
const modules = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "node_modules");
function rcodesign(args) { const result = spawnSync("rcodesign", args, { stdio: "inherit" }); if (result.status !== 0) throw new Error(`rcodesign ${args[0]} failed.`);}
export default async function afterPack(context) { // The per-architecture apps only exist to be merged into the universal // one, which is what ships. if (process.platform === "darwin" || context.electronPlatformName !== "darwin") return; if (context.arch !== Arch.universal) return;
const { APPLE_DEVELOPER_ID_PEM: pem, APPLE_NOTARY_API_KEY: apiKey } = process.env; if (!pem || !apiKey) { console.log("No Apple signing credentials, so the macOS app is left unsigned."); return; }
const app = join(context.appOutDir, `${context.packager.appInfo.productFilename}.app`); const secrets = await mkdtemp(join(tmpdir(), "diorama64-signing-")); try { const pemFile = join(secrets, "developer-id.pem"); const keyFile = join(secrets, "notary-key.json"); await writeFile(pemFile, Buffer.from(pem, "base64"), { mode: 0o600 }); await writeFile(keyFile, Buffer.from(apiKey, "base64"), { mode: 0o600 });
// The entitlements electron-builder signs Electron apps with by default. const entitlements = join(modules, "app-builder-lib", "templates", "entitlements.mac.plist"); rcodesign([ "sign", "--pem-source", pemFile, "--code-signature-flags", "runtime", "--entitlements-xml-file", entitlements, "--for-notarization", app, ]); rcodesign(["notary-submit", "--api-key-file", keyFile, "--max-wait-seconds", "3600", "--staple", app]); } finally { await rm(secrets, { recursive: true, force: true }); }}