// Ad-hoc sign the macOS bundle after electron-builder packs it. // // Why this exists: `mac.identity: null` tells electron-builder to skip signing // altogether. The .app then keeps only the linker signature that Apple put on // the prebuilt Electron binary. That signature says `Identifier=Electron`, // seals no resources, and does not bind our Info.plist. macOS reads a bundle // like that as tampered-with and shows "Malware Blocked and Moved to Trash". // // A real ad-hoc signature over the whole bundle fixes it. The app stays // unsigned in the Developer ID sense (no notarization, so a *downloaded* copy // still needs the quarantine flag cleared), but it is no longer flagged as // malware and runs fine locally. // // Replace this with a Developer ID identity + notarization when the app ships. const { execFileSync } = require('node:child_process') const path = require('node:path') exports.default = async function adhocSign(context) { if (context.electronPlatformName !== 'darwin') return const appName = context.packager.appInfo.productFilename const appPath = path.join(context.appOutDir, `${appName}.app`) const entitlements = path.join(__dirname, 'entitlements.mac.plist') console.log(` • ad-hoc signing ${appPath}`) execFileSync( 'codesign', [ '--force', '--deep', '--sign', '-', '--options', 'runtime', '--entitlements', entitlements, appPath ], { stdio: 'inherit' } ) // Fail the build rather than ship a bundle macOS will quarantine again. execFileSync('codesign', ['--verify', '--deep', '--strict', appPath], { stdio: 'inherit' }) }