Skip to content

Commit d8c2802

Browse files
authored
chore: new windows codesign process (#5)
1 parent b25a6f5 commit d8c2802

File tree

6 files changed

+144
-40
lines changed

6 files changed

+144
-40
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"configurations": [
77
{
88
"name": "Debug Release",
9-
"program": "${workspaceFolder}/scripts/release.js",
9+
"program": "${workspaceFolder}/scripts/release.mjs",
1010
"request": "launch",
1111
"skipFiles": [
1212
"<node_internals>/**"

package-lock.json

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

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"description": "Electron updater E2E test",
66
"scripts": {
77
"start": "electron ./src/main.js",
8-
"release": "node ./scripts/release.js"
8+
"release": "node ./scripts/release.mjs"
99
},
1010
"keywords": [
1111
"electron",
@@ -28,6 +28,8 @@
2828
"devDependencies": {
2929
"electron": "37.2.3",
3030
"electron-builder": "26.0.12",
31-
"fs-extra": "11.1.1"
31+
"fs-extra": "11.1.1",
32+
"p-retry": "7.1.0",
33+
"p-throttle": "8.1.0"
3234
}
3335
}
11.6 MB
Binary file not shown.

scripts/certs/windows-cert.p12.enc

-8.41 KB
Binary file not shown.
Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
2-
const exec = require('child_process').execSync
2+
import { exec, execSync } from 'node:child_process'
33

4+
const __dirname = import.meta.dirname
45
const TEST_BUILD = process.env.TEST_BUILD // set true if you would like to test on your local machine
56

67
// electron-builder security override.
@@ -26,9 +27,12 @@ if (!isReleaseCommit) {
2627
process.exit(0)
2728
}
2829

29-
const path = require('path')
30-
const builder = require('electron-builder')
31-
const fs = require('fs-extra')
30+
import path from 'node:path'
31+
import {setTimeout} from 'node:timers/promises'
32+
import builder from 'electron-builder'
33+
import fs from 'fs-extra'
34+
import pThrottle from 'p-throttle'
35+
import pRetry from 'p-retry'
3236

3337
const Platform = builder.Platform
3438
const ELECTRON_BUILD_FOLDER = path.join(__dirname, '../tmp-build')
@@ -53,10 +57,7 @@ if (process.platform === 'darwin') {
5357
if (process.platform === 'darwin') {
5458
const encryptedFile = path.join(__dirname, './certs/mac-cert.p12.enc')
5559
const decryptedFile = path.join(__dirname, './certs/mac-cert.p12')
56-
exec(`openssl aes-256-cbc -K $CERT_KEY -iv $CERT_IV -in ${encryptedFile} -out ${decryptedFile} -d`)
57-
} else if (process.platform === 'win32') {
58-
// decrypt windows certificate
59-
exec('openssl aes-256-cbc -K %CERT_KEY% -iv %CERT_IV% -in scripts/certs/windows-cert.p12.enc -out scripts/certs/windows-cert.p12 -d')
60+
execSync(`openssl aes-256-cbc -K $CERT_KEY -iv $CERT_IV -in ${encryptedFile} -out ${decryptedFile} -d`)
6061
}
6162

6263
const APPLE_TEAM_ID = 'CMXCBCFHDG'
@@ -85,8 +86,8 @@ if (TEST_BUILD || gitTag) {
8586
win: {
8687
signtoolOptions: {
8788
publisherName: 'Ultimate Gadget Laboratories Kft.',
88-
certificateFile: path.join(__dirname, 'certs/windows-cert.p12')
89-
}
89+
sign: configuration => azureKeyvaultSign(configuration.path),
90+
},
9091
},
9192
linux: {},
9293
publish: 'github',
@@ -125,3 +126,60 @@ function prepareDistDir() {
125126
electronJson.dependencies = rootJson.dependencies
126127
fs.writeJsonSync(path.join(ELECTRON_BUILD_FOLDER, 'package.json'), electronJson, { spaces: 2 })
127128
}
129+
130+
// sign only 1 file in every 2 sec
131+
// otherwise we got random singing error
132+
// maybe related issue https://github.com/vcsjones/AzureSignTool/issues/330
133+
const throttleAzureCodeSign = pThrottle({
134+
limit: 1,
135+
interval: 2000
136+
});
137+
138+
const azureKeyvaultSign = throttleAzureCodeSign(async (filePath) => {
139+
const {
140+
AZURE_KEY_VAULT_TENANT_ID,
141+
AZURE_KEY_VAULT_CLIENT_ID,
142+
AZURE_KEY_VAULT_SECRET,
143+
AZURE_KEY_VAULT_URL,
144+
AZURE_KEY_VAULT_CERTIFICATE,
145+
} = process.env;
146+
147+
if (!AZURE_KEY_VAULT_URL) {
148+
console.log('Skipping code signing, no environment variables set for that.')
149+
return
150+
}
151+
152+
return pRetry(() => new Promise((resolve, reject) => {
153+
console.log('Signing file', filePath);
154+
const signToolPath = path.join(__dirname, 'AzureSignTool-x64-6-0-1.exe')
155+
const command = `${signToolPath} sign -kvu ${AZURE_KEY_VAULT_URL} -kvi ${AZURE_KEY_VAULT_CLIENT_ID} -kvt ${AZURE_KEY_VAULT_TENANT_ID} -kvs ${AZURE_KEY_VAULT_SECRET} -kvc ${AZURE_KEY_VAULT_CERTIFICATE} -tr http://timestamp.identrust.com -v '${filePath}'`;
156+
exec(command, { shell: 'powershell.exe' }, (e, stdout, stderr) => {
157+
if (e instanceof Error) {
158+
console.error(e)
159+
return reject(e)
160+
}
161+
162+
if (stderr) {
163+
console.error(stderr)
164+
return reject(new Error(stderr))
165+
}
166+
167+
if (stdout.indexOf('Signing completed successfully') > -1) {
168+
console.log(stdout)
169+
return resolve()
170+
}
171+
172+
return reject(new Error(stdout))
173+
})
174+
}), {
175+
retries: 5,
176+
onFailedAttempt: async ({error, attemptNumber, retriesLeft, retriesConsumed}) => {
177+
console.log('Signing file failed', filePath);
178+
console.log(`Attempt ${attemptNumber} failed. ${retriesLeft} retries left. ${retriesConsumed} retries consumed.`);
179+
console.error(error)
180+
181+
console.log('wait 5 sec before retry')
182+
await setTimeout(5000)
183+
},
184+
})
185+
})

0 commit comments

Comments
 (0)