From defbe3578312f415563a2c190ed2cc89727b54b2 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 May 2016 14:49:16 -0700 Subject: [PATCH 1/2] Enable Windows codesigning via Squirrel for MSI --- build/Gruntfile.coffee | 12 +++- build/tasks/codesign-task.coffee | 94 +++++++++++++++++++------------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 16e0ed5d6..b248eda2e 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -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'] diff --git a/build/tasks/codesign-task.coffee b/build/tasks/codesign-task.coffee index 559d41bbf..13ea9f4df 100644 --- a/build/tasks/codesign-task.coffee +++ b/build/tasks/codesign-task.coffee @@ -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 From f34e4b3b13a9080e50b713a8a01d3eceb636fee8 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 May 2016 14:49:38 -0700 Subject: [PATCH 2/2] Add MSI output for AppVeyor artifact list --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 20211da8c..51e074a4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,6 +33,8 @@ deploy: off artifacts: - path: out\**\AtomSetup.exe name: AtomSetup.exe + - path: out\**\AtomSetup.msi + name: AtomSetup.msi cache: - '%USERPROFILE%\.atom\.apm'