From 7272893aed9e6a5b971398973af5c99ae81cfd76 Mon Sep 17 00:00:00 2001 From: Matt Kangas Date: Thu, 21 May 2015 17:03:50 -0400 Subject: [PATCH] fix(electron): delegate 'sign' to darwin-sign-app.sh --- scout-electron/darwin-sign-app.sh | 53 +++++++++++++++++++++++++++++++ scout-electron/gulpfile.js | 45 ++++++++++++++++---------- 2 files changed, 82 insertions(+), 16 deletions(-) create mode 100755 scout-electron/darwin-sign-app.sh diff --git a/scout-electron/darwin-sign-app.sh b/scout-electron/darwin-sign-app.sh new file mode 100755 index 00000000000..ec1f077b239 --- /dev/null +++ b/scout-electron/darwin-sign-app.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Use Apple's codesign(1) utility to ensure that users can run Scout immediately after downloading +# +# References: +# man 1 codesign +# https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html +# https://developer.apple.com/library/mac/technotes/tn2206/_index.html +# +# TODO: replace with native gulp tasks +# TODO: consider using productbuild(1) to build a .pkg. It takes care of invoking codesign +# + +set -o errexit + +if [ "$#" -ne "2" ] +then + echo "Usage: darwin-sign-app.sh " + exit 1 +fi + +# Assume two arguments; identity, path-to-app +IDENTITY="${1}" +APP_PATH="${2}" + +test -d ${APP_PATH} + +# IDENTITY is the SHA-1 signature of a Code Signing Identity obtained from Apple +# which must be accessible via the user/system keychain + +( + cd $(dirname "${APP_PATH}") + APP=$(basename "${APP_PATH}") + + # Clean up ".cstemp" files from previous attempts + find "${APP}" -name \*.cstemp -type f -delete + + for FRAMEWORK in "${APP}"/Contents/Frameworks/* + do + echo "• Signing framework: $FRAMEWORK" + codesign -s ${IDENTITY} -vvv --deep --force "$FRAMEWORK" + done + + echo "• Signing executable" + codesign -s ${IDENTITY} -vvv --force "${APP}/Contents/MacOS/Scout" + + echo "• Signing app bundle" + codesign -s ${IDENTITY} --deep -vvv --force "${APP}" + + echo + echo "• Verify" + codesign --verify -vvv "${APP}" +) diff --git a/scout-electron/gulpfile.js b/scout-electron/gulpfile.js index ddf0bc90184..a4f9028d99c 100644 --- a/scout-electron/gulpfile.js +++ b/scout-electron/gulpfile.js @@ -206,29 +206,42 @@ gulp.task('build', [ ]); // https://github.com/atom/electron-starter/blob/master/build/tasks/codesign-task.coffee -function unlockKeychain(done) { - var cmd = util.format('security unlock-keychain -p %s', - process.env.XCODE_KEYCHAIN_PASSWORD, process.env.XCODE_KEYCHAIN); - proc.exec(cmd, done); -} -function signApp(done) { - if (PLATFORM === 'darwin') { - var cmd = util.format('codesign --deep --force --verbose --sign %s %s', - process.env.XCODE_SIGNING_IDENTITY, APP); +function unlockKeychainDarwin(done) { + if (process.env.XCODE_KEYCHAIN_PASSWORD) { + var cmd = util.format('security unlock-keychain -p %s', + process.env.XCODE_KEYCHAIN_PASSWORD, process.env.XCODE_KEYCHAIN); proc.exec(cmd, done); } else { done(); } } -gulp.task('sign', function(done) { - if (process.platform() === 'darwin' && process.env.XCODE_KEYCHAIN) { - unlockKeychain(function(err) { - if (err) return done(err); - signApp(done); - }); +function signAppDarwin(done) { + if (process.env.XCODE_SIGNING_IDENTITY) { + // var cmd = util.format('codesign --deep --force --verbose --sign %s %s', + // process.env.XCODE_SIGNING_IDENTITY, APP); + + // Use a shell script until we rewrite it in gulp + var logData = function(data) { + console.log((''+ data).trim()); + }; + + var script = proc.spawn("./darwin-sign-app.sh", + [process.env.XCODE_SIGNING_IDENTITY, APP]); + script.stdout.on('data', logData); + script.stderr.on('data', logData); + script.on('close', done); } else { - return done(); + done(new Error("process.env.XCODE_SIGNING_IDENTITY not specified")); } +} +gulp.task('sign', function(done) { + if (PLATFORM !== 'darwin') { + done(new Error("sign only implemented for OS X")); + } + unlockKeychainDarwin(function(err) { + if (err) return done(err); + signAppDarwin(done); + }); }); // gulp.task('get mongo', function(cb) {