diff --git a/script/build b/script/build index c3efddd3b..930aed929 100755 --- a/script/build +++ b/script/build @@ -10,6 +10,7 @@ require('./bootstrap') require('coffee-script/register') require('colors') +const path = require('path') const yargs = require('yargs') const argv = yargs .usage('Usage: $0 [options]') @@ -75,34 +76,40 @@ binariesPromise .then(packageApplication) .then(packagedAppPath => generateStartupSnapshot(packagedAppPath).then(() => packagedAppPath)) .then(packagedAppPath => { - if (process.platform === 'darwin') { - if (argv.codeSign) { - codeSignOnMac(packagedAppPath) - } else { - console.log('Skipping code-signing. Specify the --code-sign option to perform code-signing'.gray) - } - } else if (process.platform === 'win32') { - if (argv.createWindowsInstaller) { - return createWindowsInstaller(packagedAppPath, argv.codeSign).then(() => packagedAppPath) - } else { - console.log('Skipping creating installer. Specify the --create-windows-installer option to create a Squirrel-based Windows installer.'.gray) + switch (process.platform) { + case 'darwin': { if (argv.codeSign) { - codeSignOnWindows(packagedAppPath) + codeSignOnMac(packagedAppPath) } else { console.log('Skipping code-signing. Specify the --code-sign option to perform code-signing'.gray) } } - } else if (process.platform === 'linux') { - if (argv.createDebianPackage) { - createDebianPackage(packagedAppPath) - } else { - console.log('Skipping creating debian package. Specify the --create-debian-package option to create it.'.gray) + case 'win32': { + if (argv.codeSign) { + codeSignOnWindows(path.join(packagedAppPath, 'Atom.exe')) + } else { + console.log('Skipping code-signing. Specify the --code-sign option to perform code-signing'.gray) + } + if (argv.createWindowsInstaller) { + return createWindowsInstaller(packagedAppPath) + .then(() => argv.codeSign && codeSignOnWindows(path.join(CONFIG.buildOutputPath, 'AtomSetup.exe'))) + .then(() => packagedAppPath) + } else { + console.log('Skipping creating installer. Specify the --create-windows-installer option to create a Squirrel-based Windows installer.'.gray) + } } + case 'linux': { + if (argv.createDebianPackage) { + createDebianPackage(packagedAppPath) + } else { + console.log('Skipping creating debian package. Specify the --create-debian-package option to create it.'.gray) + } - if (argv.createRpmPackage) { - createRpmPackage(packagedAppPath) - } else { - console.log('Skipping creating rpm package. Specify the --create-rpm-package option to create it.'.gray) + if (argv.createRpmPackage) { + createRpmPackage(packagedAppPath) + } else { + console.log('Skipping creating rpm package. Specify the --create-rpm-package option to create it.'.gray) + } } } diff --git a/script/lib/code-sign-on-windows.js b/script/lib/code-sign-on-windows.js index a4137c726..d37acdd59 100644 --- a/script/lib/code-sign-on-windows.js +++ b/script/lib/code-sign-on-windows.js @@ -4,10 +4,7 @@ const os = require('os') const path = require('path') const {spawnSync} = require('child_process') -// This is only used when specifying --code-sign WITHOUT --create-windows-installer -// as Squirrel has to take care of code-signing in order to correctly wrap during the building of setup - -module.exports = function (packagedAppPath) { +module.exports = function (fileToSignPath) { if (!process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) { console.log('Skipping code signing because the ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable is not defined'.gray) return @@ -19,25 +16,24 @@ module.exports = function (packagedAppPath) { downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) } try { - console.log(`Code-signing application at ${packagedAppPath}`) - signFile(path.join(packagedAppPath, 'atom.exe')) + console.log(`Code-signing executable at ${fileToSignPath}`) + signFile(fileToSignPath) } finally { if (!process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) { - console.log(`Deleting certificate at ${certPath}`) fs.removeSync(certPath) } } - function signFile (filePath) { + function signFile (fileToSignPath) { const signCommand = path.resolve(__dirname, '..', 'node_modules', 'electron-winstaller', 'vendor', 'signtool.exe') - const args = [ // Changing any of these should also be done in create-windows-installer.js + const args = [ 'sign', `/f ${certPath}`, // Signing cert file `/p ${process.env.ATOM_WIN_CODE_SIGNING_CERT_PASSWORD}`, // Signing cert password '/fd sha256', // File digest algorithm '/tr http://timestamp.digicert.com', // Time stamp server '/td sha256', // Times stamp algorithm - `"${filePath}"` + `"${fileToSignPath}"` ] const result = spawnSync(signCommand, args, {stdio: 'inherit', shell: true}) if (result.status !== 0) { diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index e8494b06d..ddc46d484 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -1,16 +1,13 @@ 'use strict' -const downloadFileFromGithub = require('./download-file-from-github') const electronInstaller = require('electron-winstaller') const fs = require('fs-extra') const glob = require('glob') -const os = require('os') const path = require('path') -const spawnSync = require('./spawn-sync') const CONFIG = require('../config') -module.exports = (packagedAppPath, codeSign) => { +module.exports = (packagedAppPath) => { const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch const options = { appDirectory: packagedAppPath, @@ -23,32 +20,7 @@ module.exports = (packagedAppPath, codeSign) => { setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico') } - const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) - let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH - - if (signing) { - if (!certPath) { - certPath = path.join(os.tmpdir(), 'win.p12') - downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) - } - - var signParams = [] // Changing any of these should also be done in code-sign-on-windows.js - signParams.push(`/f ${certPath}`) // Signing cert file - signParams.push(`/p ${process.env.ATOM_WIN_CODE_SIGNING_CERT_PASSWORD}`) // Signing cert password - signParams.push('/fd sha256') // File digest algorithm - signParams.push('/tr http://timestamp.digicert.com') // Time stamp server - signParams.push('/td sha256') // Times stamp algorithm - options.signWithParams = signParams.join(' ') - } else { - console.log('Skipping code-signing. Specify the --code-sign option and provide a ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable to perform code-signing'.gray) - } - const cleanUp = () => { - if (fs.existsSync(certPath) && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) { - console.log(`Deleting certificate at ${certPath}`) - fs.removeSync(certPath) - } - for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*.nupkg`)) { if (!nupkgPath.includes(CONFIG.appMetadata.version)) { console.log(`Deleting downloaded nupkg for previous version at ${nupkgPath} to prevent it from being stored as an artifact`) @@ -57,24 +29,8 @@ module.exports = (packagedAppPath, codeSign) => { } } - // Squirrel signs its own copy of the executables but we need them for the portable ZIP - const extractSignedExes = () => { - if (signing) { - for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) { - if (nupkgPath.includes(CONFIG.appMetadata.version)) { - nupkgPath = path.resolve(nupkgPath) // Switch from forward-slash notation - console.log(`Extracting signed executables from ${nupkgPath} for use in portable zip`) - spawnSync('7z.exe', ['e', nupkgPath, 'lib\\net45\\*.exe', '-aoa', `-o${packagedAppPath}`]) - spawnSync(process.env.COMSPEC, ['/c', 'move', '/y', path.join(packagedAppPath, 'squirrel.exe'), path.join(packagedAppPath, 'update.exe')]) - return - } - } - } - } - console.log(`Creating Windows Installer for ${packagedAppPath}`) return electronInstaller.createWindowsInstaller(options) - .then(extractSignedExes) .then(cleanUp, error => { cleanUp() return Promise.reject(error)