Skip to content

Commit 88b1da1

Browse files
authored
Merge pull request scratchfoundation#96 from cwillisf/notarize-mac-build
Notarize macOS build
2 parents 5f5f24e + 5c2303a commit 88b1da1

File tree

7 files changed

+86
-3
lines changed

7 files changed

+86
-3
lines changed

buildResources/entitlements.inherit.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<dict>
55
<key>com.apple.security.app-sandbox</key>
66
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
79
<key>com.apple.security.inherit</key>
810
<true/>
911
</dict>

buildResources/entitlements.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<dict>
55
<key>com.apple.security.app-sandbox</key>
66
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
79
<key>com.apple.security.device.audio-input</key>
810
<true/>
911
<key>com.apple.security.device.camera</key>

electron-builder.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ directories:
33
output: dist
44
appId: edu.mit.scratch.scratch-desktop
55
productName: "Scratch Desktop"
6+
afterSign: "scripts/afterSign.js"
67
mac:
78
category: public.app-category.education
9+
hardenedRuntime: true
810
icon: buildResources/ScratchDesktop.icns
911
provisioningProfile: embedded.provisionprofile
1012
target:

package-lock.json

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"electron": "^6.1.7",
3939
"electron-builder": "^22.2.0",
4040
"electron-devtools-installer": "^2.2.4",
41+
"electron-notarize": "^0.2.1",
4142
"electron-store": "^3.3.0",
4243
"electron-webpack": "^2.7.4",
4344
"eslint": "^5.16.0",

scripts/afterSign.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const {notarize} = require('electron-notarize');
2+
3+
const notarizeMacBuild = async function (context) {
4+
// keep this in sync with appId in the electron-builder config
5+
const appId = 'edu.mit.scratch.scratch-desktop';
6+
7+
if (!process.env.AC_USERNAME) {
8+
throw new Error(
9+
'Notarizing the macOS build requires an Apple ID.\n' +
10+
'Please set the environment variable AC_USERNAME.\n' +
11+
'Make sure your keychain has an item for "Application Loader: [email protected]"'
12+
);
13+
}
14+
15+
const appleId = process.env.AC_USERNAME;
16+
const appleIdKeychainItem = `Application Loader: ${appleId}`;
17+
18+
console.log(`Notarizing with Apple ID "${appleId}" and keychain item "${appleIdKeychainItem}"`);
19+
20+
const {appOutDir} = context;
21+
const productFilename = context.packager.appInfo.productFilename;
22+
await notarize({
23+
appBundleId: appId,
24+
appPath: `${appOutDir}/${productFilename}.app`,
25+
appleId,
26+
appleIdPassword: `@keychain:${appleIdKeychainItem}`
27+
});
28+
};
29+
30+
const afterSign = async function (context) {
31+
const {electronPlatformName} = context;
32+
33+
switch (electronPlatformName) {
34+
case 'mas': // macOS build for Mac App Store
35+
break;
36+
case 'darwin': // macOS build NOT for Mac App Store
37+
await notarizeMacBuild(context);
38+
break;
39+
}
40+
};
41+
42+
module.exports = afterSign;

scripts/electron-builder-wrapper.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,20 @@ const runBuilder = function (targetGroup) {
5252
const platformFlag = getPlatformFlag();
5353
const command = `electron-builder ${platformFlag} ${targetGroup}`;
5454
console.log(`running: ${command}`);
55-
spawnSync(command, {
55+
const result = spawnSync(command, {
5656
env: childEnvironment,
5757
shell: true,
5858
stdio: 'inherit'
5959
});
60+
if (result.error) {
61+
throw result.error;
62+
}
63+
if (result.signal) {
64+
throw new Error(`Child process terminated due to signal ${result.signal}`);
65+
}
66+
if (result.status) {
67+
throw new Error(`Child process returned status code ${result.status}`);
68+
}
6069
};
6170

6271
/**
@@ -69,8 +78,10 @@ const calculateTargets = function () {
6978
// run in two passes so we can skip signing the appx
7079
return ['nsis', 'appx'];
7180
case 'darwin':
72-
// run in one pass for slightly better speed
73-
return ['dmg mas'];
81+
// Running 'dmg' and 'mas' in the same pass causes electron-builder to skip signing the non-MAS app copy.
82+
// Running them as separate passes means they both get signed.
83+
// Seems like a bug in electron-builder...
84+
return ['dmg', 'mas'];
7485
}
7586
throw new Error(`Could not determine targets for platform: ${process.platform}`);
7687
};

0 commit comments

Comments
 (0)