Enable Windows codesigning via Squirrel for MSI

This commit is contained in:
Damien Guard
2016-05-19 14:49:16 -07:00
parent 73525a1bcc
commit defbe35783
2 changed files with 65 additions and 41 deletions

View File

@@ -172,6 +172,8 @@ module.exports = (grunt) ->
dest: path.join(appDir, jsFile)
})
windowsInstallerConfig =
grunt.initConfig
pkg: grunt.file.readJSON('package.json')
@@ -286,12 +288,16 @@ module.exports = (grunt) ->
ciTasks.push('set-version', 'check-licenses', 'lint', 'generate-asar')
ciTasks.push('mkdeb') if process.platform is 'linux'
ciTasks.push('mktar') if process.platform is 'linux'
ciTasks.push('codesign:exe') if process.platform is 'win32' and not process.env.CI
ciTasks.push('create-windows-installer:installer') if process.platform is 'win32'
ciTasks.push('test') if process.platform is 'darwin'
ciTasks.push('codesign:installer') if process.platform is 'win32' and not process.env.CI
ciTasks.push('codesign:app') if process.platform is 'darwin' and not process.env.CI
if process.platform is 'win32'
ciTasks.push('codesign:exe') if process.env.JANKY_SIGNTOOL
ciTasks.push('codesign:installer-deferred') if not process.env.JANKY_SIGNTOOL
ciTasks.push('create-windows-installer:installer')
ciTasks.push('codesign:installer') if process.env.JANKY_SIGNTOOL
ciTasks.push('codesign:cleanup')
ciTasks.push('publish-build') unless process.env.CI
grunt.registerTask('ci', ciTasks)
defaultTasks = ['download-electron', 'download-electron-chromedriver', 'build', 'set-version', 'generate-asar']

View File

@@ -5,46 +5,10 @@ request = require 'request'
module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
signUsingWindowsSDK = (exeToSign, callback) ->
{WIN_P12KEY_PASSWORD, WIN_P12KEY_URL} = process.env
if WIN_P12KEY_URL?
grunt.log.ok("Obtaining signing key")
downloadedKeyFile = path.resolve(__dirname, 'DownloadedSignKey.p12')
downloadFile WIN_P12KEY_URL, downloadedKeyFile, (done) ->
signUsingWindowsSDKTool exeToSign, downloadedKeyFile, WIN_P12KEY_PASSWORD, (done) ->
fs.unlinkSync(downloadedKeyFile)
callback()
else
signUsingWindowsSDKTool exeToSign, path.resolve(__dirname, '..', 'certs', 'AtomDevTestSignKey.p12'), 'password', callback
signUsingWindowsSDKTool = (exeToSign, keyFilePath, password, callback) ->
grunt.log.ok("Signing #{exeToSign}")
args = ['sign', '/v', '/p', password, '/f', keyFilePath, exeToSign]
spawn {cmd: 'C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\bin\\signtool.exe', args: args}, callback
signUsingJanky = (exeToSign, callback) ->
spawn {cmd: process.env.JANKY_SIGNTOOL, args: [exeToSign]}, callback
signWindowsExecutable = if process.env.JANKY_SIGNTOOL then signUsingJanky else signUsingWindowsSDK
grunt.registerTask 'codesign:exe', 'CodeSign Atom.exe and Update.exe', ->
done = @async()
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
atomExePath = path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')
signWindowsExecutable atomExePath, (error) ->
return done(error) if error?
updateExePath = path.resolve(__dirname, '..', 'node_modules', 'grunt-electron-installer', 'vendor', 'Update.exe')
signWindowsExecutable updateExePath, (error) -> done(error)
grunt.registerTask 'codesign:installer', 'CodeSign AtomSetup.exe', ->
done = @async()
atomSetupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
signWindowsExecutable atomSetupExePath, (error) -> done(error)
# Mac OS X code signing
grunt.registerTask 'codesign:app', 'CodeSign Atom.app', ->
done = @async()
unlockKeychain (error) ->
return done(error) if error?
@@ -53,11 +17,65 @@ module.exports = (grunt) ->
unlockKeychain = (callback) ->
return callback() unless process.env.XCODE_KEYCHAIN
{XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN} = process.env
args = ['unlock-keychain', '-p', XCODE_KEYCHAIN_PASSWORD, XCODE_KEYCHAIN]
spawn {cmd: 'security', args: args}, (error) -> callback(error)
# Windows code signing
grunt.registerTask 'codesign:exe', 'CodeSign Windows binaries', ->
done = @async()
atomExePath = path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')
signWindowsExecutable atomExePath, (error) ->
return done(error) if error?
updateExePath = path.resolve(__dirname, '..', 'node_modules', 'grunt-electron-installer', 'vendor', 'Update.exe')
signWindowsExecutable updateExePath, (error) -> done(error)
grunt.registerTask 'codesign:installer', 'CodeSign Windows installer (AtomSetup.exe)', ->
done = @async()
atomSetupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
signWindowsExecutable atomSetupExePath, (error) -> done(error)
grunt.registerTask 'codesign:installer-deferred', 'Obtain cert and configure installer to perform CodeSign', ->
done = @async()
getCertificate (file, password) ->
grunt.config('create-windows-installer.installer.certificateFile', file)
grunt.config('create-windows-installer.installer.certificatePassword', password)
grunt.log.ok('Certificate ready for create-windows-installer task')
done()
grunt.registerTask 'codesign:cleanup', 'Clean up any temporary or downloaded files used for CodeSign', ->
try fs.unlinkSync(downloadedCertificateFile) catch e then return
downloadedCertificateFile = path.resolve(__dirname, 'DownloadedCertFile.p12')
signWindowsExecutable = (exeToSign, callback) ->
if process.env.JANKY_SIGNTOOL
signUsingJanky exeToSign, callback
else
signUsingWindowsSDK exeToSign, callback
signUsingJanky = (exeToSign, callback) ->
grunt.log.ok("Signing #{exeToSign} using Janky SignTool")
spawn {cmd: process.env.JANKY_SIGNTOOL, args: [exeToSign]}, callback
signUsingWindowsSDK = (exeToSign, callback) ->
getCertificate (file, password) ->
signUsingWindowsSDKTool exeToSign, file, password, callback
signUsingWindowsSDKTool = (exeToSign, certificateFile, certificatePassword, callback) ->
grunt.log.ok("Signing '#{exeToSign}' using Windows SDK")
args = ['sign', '/v', '/p', certificatePassword, '/f', certificateFile, exeToSign]
spawn {cmd: 'C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\bin\\signtool.exe', args: args}, callback
getCertificate = (callback) ->
if process.env.WIN_P12KEY_URL?
grunt.log.ok("Obtaining certificate file")
downloadFile process.env.WIN_P12KEY_URL, downloadedCertificateFile, (done) ->
callback(downloadedCertificateFile, process.env.WIN_P12KEY_PASSWORD ? 'password')
else
callback(path.resolve(__dirname, '..', 'certs', 'AtomDevTestSignKey.p12'), process.env.WIN_P12KEY_PASSWORD ? 'password')
downloadFile = (sourceUrl, targetPath, callback) ->
options = {
url: sourceUrl