Skip to content

Commit f89b273

Browse files
damiengMichelle Tilley
authored andcommitted
Enable Windows codesigning via Squirrel for MSI
(cherry picked from commit defbe35)
1 parent 19e959b commit f89b273

File tree

2 files changed

+64
-40
lines changed

2 files changed

+64
-40
lines changed

build/Gruntfile.coffee

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ module.exports = (grunt) ->
172172
dest: path.join(appDir, jsFile)
173173
})
174174

175+
windowsInstallerConfig =
176+
175177
grunt.initConfig
176178
pkg: grunt.file.readJSON('package.json')
177179

@@ -286,12 +288,16 @@ module.exports = (grunt) ->
286288
ciTasks.push('set-version', 'check-licenses', 'lint', 'generate-asar')
287289
ciTasks.push('mkdeb') if process.platform is 'linux'
288290
ciTasks.push('mktar') if process.platform is 'linux'
289-
ciTasks.push('codesign:exe') if process.platform is 'win32' and not process.env.CI
290-
ciTasks.push('create-windows-installer:installer') if process.platform is 'win32'
291291
ciTasks.push('test') if process.platform is 'darwin'
292-
ciTasks.push('codesign:installer') if process.platform is 'win32' and not process.env.CI
293292
ciTasks.push('codesign:app') if process.platform is 'darwin' and not process.env.CI
293+
if process.platform is 'win32'
294+
ciTasks.push('codesign:exe') if process.env.JANKY_SIGNTOOL
295+
ciTasks.push('codesign:installer-deferred') if not process.env.JANKY_SIGNTOOL
296+
ciTasks.push('create-windows-installer:installer')
297+
ciTasks.push('codesign:installer') if process.env.JANKY_SIGNTOOL
298+
ciTasks.push('codesign:cleanup')
294299
ciTasks.push('publish-build') unless process.env.CI
300+
295301
grunt.registerTask('ci', ciTasks)
296302

297303
defaultTasks = ['download-electron', 'download-electron-chromedriver', 'build', 'set-version', 'generate-asar']

build/tasks/codesign-task.coffee

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,76 @@ request = require 'request'
55
module.exports = (grunt) ->
66
{spawn} = require('./task-helpers')(grunt)
77

8-
signUsingWindowsSDK = (exeToSign, callback) ->
9-
{WIN_P12KEY_PASSWORD, WIN_P12KEY_URL} = process.env
10-
if WIN_P12KEY_URL?
11-
grunt.log.ok("Obtaining signing key")
12-
downloadedKeyFile = path.resolve(__dirname, 'DownloadedSignKey.p12')
13-
downloadFile WIN_P12KEY_URL, downloadedKeyFile, (done) ->
14-
signUsingWindowsSDKTool exeToSign, downloadedKeyFile, WIN_P12KEY_PASSWORD, (done) ->
15-
fs.unlinkSync(downloadedKeyFile)
16-
callback()
17-
else
18-
signUsingWindowsSDKTool exeToSign, path.resolve(__dirname, '..', 'certs', 'AtomDevTestSignKey.p12'), 'password', callback
8+
# Mac OS X code signing
199

20-
signUsingWindowsSDKTool = (exeToSign, keyFilePath, password, callback) ->
21-
grunt.log.ok("Signing #{exeToSign}")
22-
args = ['sign', '/v', '/p', password, '/f', keyFilePath, exeToSign]
23-
spawn {cmd: 'C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\bin\\signtool.exe', args: args}, callback
10+
grunt.registerTask 'codesign:app', 'CodeSign Atom.app', ->
11+
done = @async()
12+
unlockKeychain (error) ->
13+
return done(error) if error?
2414

25-
signUsingJanky = (exeToSign, callback) ->
26-
spawn {cmd: process.env.JANKY_SIGNTOOL, args: [exeToSign]}, callback
15+
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
16+
spawn {cmd: 'codesign', args: args}, (error) -> done(error)
2717

28-
signWindowsExecutable = if process.env.JANKY_SIGNTOOL then signUsingJanky else signUsingWindowsSDK
18+
unlockKeychain = (callback) ->
19+
return callback() unless process.env.XCODE_KEYCHAIN
20+
{XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN} = process.env
21+
args = ['unlock-keychain', '-p', XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN]
22+
spawn {cmd: 'security', args: args}, (error) -> callback(error)
2923

30-
grunt.registerTask 'codesign:exe', 'CodeSign Atom.exe and Update.exe', ->
31-
done = @async()
32-
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
33-
atomExePath = path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')
34-
signWindowsExecutable atomExePath, (error) ->
35-
return done(error) if error?
24+
# Windows code signing
3625

37-
updateExePath = path.resolve(__dirname, '..', 'node_modules', 'grunt-electron-installer', 'vendor', 'Update.exe')
38-
signWindowsExecutable updateExePath, (error) -> done(error)
26+
grunt.registerTask 'codesign:exe', 'CodeSign Windows binaries', ->
27+
done = @async()
28+
atomExePath = path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')
29+
signWindowsExecutable atomExePath, (error) ->
30+
return done(error) if error?
31+
updateExePath = path.resolve(__dirname, '..', 'node_modules', 'grunt-electron-installer', 'vendor', 'Update.exe')
32+
signWindowsExecutable updateExePath, (error) -> done(error)
3933

40-
grunt.registerTask 'codesign:installer', 'CodeSign AtomSetup.exe', ->
34+
grunt.registerTask 'codesign:installer', 'CodeSign Windows installer (AtomSetup.exe)', ->
4135
done = @async()
4236
atomSetupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
4337
signWindowsExecutable atomSetupExePath, (error) -> done(error)
4438

45-
grunt.registerTask 'codesign:app', 'CodeSign Atom.app', ->
39+
grunt.registerTask 'codesign:installer-deferred', 'Obtain cert and configure installer to perform CodeSign', ->
4640
done = @async()
41+
getCertificate (file, password) ->
42+
grunt.config('create-windows-installer.installer.certificateFile', file)
43+
grunt.config('create-windows-installer.installer.certificatePassword', password)
44+
grunt.log.ok('Certificate ready for create-windows-installer task')
45+
done()
4746

48-
unlockKeychain (error) ->
49-
return done(error) if error?
47+
grunt.registerTask 'codesign:cleanup', 'Clean up any temporary or downloaded files used for CodeSign', ->
48+
try fs.unlinkSync(downloadedCertificateFile) catch e then return
5049

51-
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
52-
spawn {cmd: 'codesign', args: args}, (error) -> done(error)
50+
downloadedCertificateFile = path.resolve(__dirname, 'DownloadedCertFile.p12')
5351

54-
unlockKeychain = (callback) ->
55-
return callback() unless process.env.XCODE_KEYCHAIN
52+
signWindowsExecutable = (exeToSign, callback) ->
53+
if process.env.JANKY_SIGNTOOL
54+
signUsingJanky exeToSign, callback
55+
else
56+
signUsingWindowsSDK exeToSign, callback
5657

57-
{XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN} = process.env
58-
args = ['unlock-keychain', '-p', XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN]
59-
spawn {cmd: 'security', args: args}, (error) -> callback(error)
58+
signUsingJanky = (exeToSign, callback) ->
59+
grunt.log.ok("Signing #{exeToSign} using Janky SignTool")
60+
spawn {cmd: process.env.JANKY_SIGNTOOL, args: [exeToSign]}, callback
61+
62+
signUsingWindowsSDK = (exeToSign, callback) ->
63+
getCertificate (file, password) ->
64+
signUsingWindowsSDKTool exeToSign, file, password, callback
65+
66+
signUsingWindowsSDKTool = (exeToSign, certificateFile, certificatePassword, callback) ->
67+
grunt.log.ok("Signing '#{exeToSign}' using Windows SDK")
68+
args = ['sign', '/v', '/p', certificatePassword, '/f', certificateFile, exeToSign]
69+
spawn {cmd: 'C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\bin\\signtool.exe', args: args}, callback
70+
71+
getCertificate = (callback) ->
72+
if process.env.WIN_P12KEY_URL?
73+
grunt.log.ok("Obtaining certificate file")
74+
downloadFile process.env.WIN_P12KEY_URL, downloadedCertificateFile, (done) ->
75+
callback(downloadedCertificateFile, process.env.WIN_P12KEY_PASSWORD ? 'password')
76+
else
77+
callback(path.resolve(__dirname, '..', 'certs', 'AtomDevTestSignKey.p12'), process.env.WIN_P12KEY_PASSWORD ? 'password')
6078

6179
downloadFile = (sourceUrl, targetPath, callback) ->
6280
options = {

0 commit comments

Comments
 (0)