Skip to content

Commit 3314d55

Browse files
feat: macOS code signing and notarization setup
1 parent 6f76cf5 commit 3314d55

6 files changed

Lines changed: 111 additions & 15 deletions

File tree

.github/workflows/release.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,24 @@ jobs:
8989
_APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
9090
run: |
9191
if [ -n "$_APPLE_CERTIFICATE" ]; then
92-
echo "$_APPLE_CERTIFICATE" | base64 --decode > certificate.p12
93-
security create-keychain -p "temp-keychain-password" build.keychain
94-
security import certificate.p12 -k build.keychain \
95-
-P "$_APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
96-
security list-keychains -s build.keychain
97-
security default-keychain -s build.keychain
98-
security unlock-keychain -p "temp-keychain-password" build.keychain
92+
KEYCHAIN_PASSWORD="$(openssl rand -hex 16)"
93+
echo "$_APPLE_CERTIFICATE" | base64 --decode > /tmp/certificate.p12
94+
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
95+
security set-keychain-settings -lut 21600 build.keychain
96+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
97+
security import /tmp/certificate.p12 -k build.keychain \
98+
-P "$_APPLE_CERTIFICATE_PASSWORD" \
99+
-T /usr/bin/codesign -T /usr/bin/security
100+
security list-keychains -d user -s build.keychain login.keychain
99101
security set-key-partition-list \
100-
-S apple-tool:,apple:,codesign: -s -k "temp-keychain-password" build.keychain
101-
rm certificate.p12
102+
-S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
103+
rm /tmp/certificate.p12
102104
echo "CSC_IDENTITY_AUTO_DISCOVERY=true" >> $GITHUB_ENV
103-
echo "✓ Developer ID certificate imported — full signing enabled."
105+
echo "✓ Developer ID certificate imported — full signing + notarization enabled."
104106
else
105107
echo "CSC_IDENTITY=-" >> $GITHUB_ENV
106108
echo "CSC_IDENTITY_AUTO_DISCOVERY=false" >> $GITHUB_ENV
107-
echo " No certificate — using ad-hoc signing."
109+
echo " No certificate found — using ad-hoc signing (won't run on other Macs)."
108110
fi
109111
110112
# Set Windows signing env only when the cert secret is actually configured.

package-lock.json

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

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
6060
"@electron-toolkit/eslint-config-ts": "^2.0.0",
6161
"@electron-toolkit/tsconfig": "^1.0.1",
62+
"@electron/notarize": "^2.5.0",
6263
"@electron/rebuild": "^3.7.2",
6364
"@types/better-sqlite3": "^7.6.13",
6465
"@types/node": "^20.14.9",
@@ -100,13 +101,18 @@
100101
"node_modules/better-sqlite3-multiple-ciphers/**/*",
101102
"node_modules/@serialport/bindings-cpp/**/*"
102103
],
104+
"afterSign": "scripts/notarize.js",
103105
"mac": {
104106
"category": "public.app-category.developer-tools",
105107
"target": [
106108
"dmg",
107109
"zip"
108110
],
109-
"icon": "resources/icon.icns"
111+
"icon": "resources/icon.icns",
112+
"hardenedRuntime": true,
113+
"gatekeeperAssess": false,
114+
"entitlements": "resources/entitlements.mac.plist",
115+
"entitlementsInherit": "resources/entitlements.mac.inherit.plist"
110116
},
111117
"win": {
112118
"target": [
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-jit</key>
6+
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
9+
<key>com.apple.security.cs.disable-library-validation</key>
10+
<true/>
11+
<key>com.apple.security.network.client</key>
12+
<true/>
13+
<key>com.apple.security.network.server</key>
14+
<true/>
15+
</dict>
16+
</plist>

resources/entitlements.mac.plist

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-jit</key>
6+
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
9+
<key>com.apple.security.cs.disable-library-validation</key>
10+
<true/>
11+
<key>com.apple.security.network.client</key>
12+
<true/>
13+
<key>com.apple.security.network.server</key>
14+
<true/>
15+
</dict>
16+
</plist>

scripts/notarize.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const { notarize } = require('@electron/notarize')
2+
3+
exports.default = async function notarizing(context) {
4+
if (context.electronPlatformName !== 'darwin') return
5+
if (!process.env.APPLE_ID) {
6+
console.log('Skipping notarization: APPLE_ID not set')
7+
return
8+
}
9+
10+
const appName = context.packager.appInfo.productFilename
11+
const appPath = `${context.appOutDir}/${appName}.app`
12+
13+
console.log(`Notarizing ${appPath}...`)
14+
15+
await notarize({
16+
tool: 'notarytool',
17+
appPath,
18+
appleId: process.env.APPLE_ID,
19+
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
20+
teamId: process.env.APPLE_TEAM_ID,
21+
})
22+
23+
console.log('Notarization complete.')
24+
}

0 commit comments

Comments
 (0)