Last active
September 21, 2016 01:15
-
-
Save masonicGIT/a613b12aa4ddeb7c3907a9802963d4e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Electron build & sign utility script | |
# | |
# Requirements: | |
# - ITMS transporter | |
# - Application Loader | |
# | |
# | |
# 1. Set all necessary variables below (APP, APP_KEY, INSTALLER_KEY, BUNDLE_ID) | |
# 2. Run the electron packager on your node application folder. | |
# | |
# APP_KEY - "3rd Party Mac Developer Application: Adam Smith (2U14V9M123)" | |
# INSTALLER_KEY - "3rd Party Mac Developer Installer: Adam Smith (2U11V1M123)" | |
# BUNDLE_ID - This must be the App ID from your apple developer portal | |
# APP_NAME - The name of your application | |
APP_KEY="" | |
INSTALLER_KEY="" | |
BUNDLE_ID="org.voluntary.bitmarkets" | |
APP_NAME="Bitmarkets.app" | |
# | |
# 3. Run the script with the following: | |
# | |
# bash build.sh <path to application> <app-version> <electron version> | |
# | |
## | |
## Set the necessary command-line arguments | |
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] | |
then | |
echo "Please set your apple developer path to your .app folder, your app version, and your preferred electron version" | |
echo "bash build.sh <path-to-.app> <app build version> <electron version>" | |
exit 1 | |
fi | |
APP=${APP_NAME%.*} | |
PRODUCTION_FOLDER="Production" | |
PROD_APP="$PRODUCTION_FOLDER/$APP_NAME" | |
RESULT_PATH="$PRODUCTION_FOLDER/$APP.pkg" | |
PROD_APP_FOLDER="$PRODUCTION_FOLDER/$APP_NAME/Contents/Resources/app" | |
FRAMEWORKS_PATH="$PROD_APP/Contents/Frameworks" | |
ALTOOL="/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool" | |
if [ -d "Bitmarkets-mas-x64" ] ; then | |
echo "Removing existing mas directory" | |
rm -rf Bitmarkets-mas-x64 | |
fi | |
electron-packager $1 --name="bitmarkets" --platform=mas --arch=x64 --version $3 --overwrite --app-bundle-id=$BUNDLE_ID --build-version=$2 | |
# -------------------------------------------------------------------- | |
# Create a Production folder and copy the electron app folder into it. | |
# -------------------------------------------------------------------- | |
eval rm -rf $PRODUCTION_FOLDER | |
mkdir $PRODUCTION_FOLDER | |
echo "► Removed old Production folder" | |
mv Bitmarkets-mas-x64/Bitmarkets.app $PRODUCTION_FOLDER/ | |
rm -rf Bitmarkets-mas-x64 | |
echo "► Copied app to Production" | |
# -------------------------------------------------------------------- | |
# Run the node script bundle.js to package up all the JS source | |
# files into one file (bundle.js). | |
# -------------------------------------------------------------------- | |
node bundle_js.js "$PROD_APP_FOLDER/source" "$PROD_APP_FOLDER/bundle.js" | |
echo "► Bundled javascript" | |
# -------------------------------------------------------------------- | |
# Run bundle_css.js which does the same for the css files (into bundle.css). | |
# -------------------------------------------------------------------- | |
node bundle_css.js "$PROD_APP_FOLDER/source" "$PROD_APP_FOLDER/bundle.css" | |
echo "► Bundled css" | |
# -------------------------------------------------------------------- | |
# Run uglifyjs on bundle.js to produce bundle.min.js. | |
# -------------------------------------------------------------------- | |
uglifyjs "$PROD_APP_FOLDER/bundle.js" --keep-fnames -c -o "$PROD_APP_FOLDER/bundle.min.js" 2> /dev/null | |
cp "$PROD_APP_FOLDER/bundle.js" "$PROD_APP_FOLDER/bundle.min.js" | |
echo "► Minified javascript" | |
# -------------------------------------------------------------------- | |
# Removes unneeded files | |
# -------------------------------------------------------------------- | |
rm "$PROD_APP_FOLDER/bundle.js" | |
rm -rf "$PROD_APP_FOLDER/source" | |
echo "► Removed unminified js" | |
rm "$PROD_APP_FOLDER/index.html" | |
mv "$PROD_APP_FOLDER/index_release.html" "$PROD_APP_FOLDER/index.html" | |
echo "► Switching to production index.html" | |
# ---------------------------------- | |
find "$PROD_APP" -name "*.o" -type f -delete | |
echo "► Removed any .o files" | |
# ---------------------------------- | |
rm $PROD_APP_FOLDER/node_modules/*/*.markdown | |
rm $PROD_APP_FOLDER/node_modules/*/*.md | |
rm $PROD_APP_FOLDER/node_modules/*/LICENSE.txt | |
rm $PROD_APP_FOLDER/node_modules/*/license | |
rm $PROD_APP_FOLDER/node_modules/*/test.js | |
rm $PROD_APP_FOLDER/node_modules/*/Makefile | |
rm -Rf $PROD_APP_FOLDER/node_modules/*/examples | |
rm -Rf $PROD_APP_FOLDER/node_modules/*/example | |
rm -Rf $PROD_APP_FOLDER/node_modules/*/test | |
echo "► Removed unneeded node_module stuff" | |
find $PROD_APP_FOLDER/node_modules/* -name 'bin' -exec rm -rf {} \; 2> /dev/null | |
rm -rf $PROD_APP_FOLDER/node_modules/.bin | |
find $PROD_APP_FOLDER/node_modules/* -name '.bin' -exec rm -rf {} \; 2> /dev/null | |
echo "► Remove all bin folders ( per codesign requirements )" | |
rm -Rf "$PROD_APP/Contents/Resources/app/node_modules/electron-prebuilt/dist/Electron.app" | |
echo "► Removed node_modules/electron-prebuilt/dist/Electron.app" | |
# -------------------------------------------------------------------- | |
# Remove some unneeded frameworks. | |
# advice from http://www.saschawise.com/blog/2015/08/12/electron-for-the-mac-app-store.html | |
# -------------------------------------------------------------------- | |
rm -rf "$PROD_APP/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/crashpad_handler" | |
rm -rf "$PROD_APP/Contents/Frameworks/Electron Framework.framework/Libraries/ffmpegsumo.so" | |
rm -rf "$PROD_APP/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt" | |
# ---------------------------------------------------- | |
# Locate the frameworks, apps, and dynamic libraries | |
# ---------------------------------------------------- | |
FRAMEWORKS="" | |
FRAMEWORKS_DIR="${FRAMEWORKS_PATH}" | |
if [ -d "$FRAMEWORKS_DIR" ] ; then | |
FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.app" -or -name "*.dylib" | sed -e "s/\(.*framework^dylib\)/\1\/Versions\/A\//" | sed 's#/*$##') | |
RESULT=$? | |
if [[ $RESULT != 0 ]] ; then | |
echo "► Encountered an error while scanning for frameworks" | |
exit 1 | |
fi | |
FRAMEWORKS="${FRAMEWORKS}" | |
fi | |
echo "► Scanned for frameworks apps and dynamic libs" | |
# --------------------------------------------------------- | |
# Locate the nested .node files in the node_modules folder | |
# --------------------------------------------------------- | |
if [ -d "$PROD_APP_FOLDER" ] ; then | |
NODEITEMS=$(find "$PROD_APP_FOLDER/node_modules" -name "*.node") | |
RESULT=$? | |
if [[ $RESULT != 0 ]] ; then | |
echo "► Encountered an error while scanning for .node files" | |
exit 1 | |
fi | |
FRAMEWORKS="${FRAMEWORKS}"$'\n'"${NODEITEMS}" | |
fi | |
echo "► Locating nested .node modules" | |
# -------------------------------------------------------------- | |
# Handle the case where there are spaces in the framework name | |
# -------------------------------------------------------------- | |
SAVED_IFS=$IFS | |
IFS=$(echo -en "\n\b") | |
echo "► Set internal field separator" | |
ROOT_DIR=$PWD | |
for FRAMEWORK in $FRAMEWORKS; | |
do | |
eval cd "${FRAMEWORKS_PATH}" | |
if [[ $FRAMEWORK == *"framework" ]] ; then | |
# Strip out the period and everything after it | |
PACKAGE=${FRAMEWORK%.*} | |
# Strip out everythinge before the framework name | |
PACKAGE=${PACKAGE#*/*/*/*/} | |
# Insert escape characters before the whitespace | |
PACKAGERAW=$PACKAGE | |
PACKAGE=${PACKAGE// /\\ } | |
PACKAGE_FOLDER="${PACKAGE}.framework" | |
# Insert escape characters before the whitespaces for the framework paths | |
FRAMEWORK=${FRAMEWORK// /\\ } | |
# Set the Versions/A symlink | |
eval cd "${PACKAGE_FOLDER}" | |
eval rm -rf "Versions/Current" | |
eval cd "Versions"; ln -s A Current | |
cd ..; | |
eval rm "${PACKAGE}" | |
ln -s Versions/Current/"${PACKAGERAW}" "${PACKAGERAW}" | |
eval rm -rf Resources | |
ln -s Versions/Current/Resources Resources | |
if [ -d "${FRAMEWORK}/Libraries" ]; then | |
eval rm -rf Libraries | |
ln -s Versions/Current/Libraries Libraries | |
fi | |
cd ..; | |
fi | |
cd $ROOT_DIR | |
done | |
echo "► Set all symlinks" | |
# -------------------------------------------------------------------- | |
# Try to fix the bundle ids of the linked frameworks to keep Apple code signing happy. | |
# -------------------------------------------------------------------- | |
sed -i "" -e "s|com\.github\.electron\.framework|$BUNDLE_ID|g" $PROD_APP/Contents/Frameworks/Electron\ Framework.framework/Resources/Info.plist | |
sed -i "" -e "s|org\.voluntary\.bitmarkets\.helper\.EH|$BUNDLE_ID|g" $PROD_APP/Contents/Frameworks/Bitmarkets\ Helper\ EH.app/Contents/Info.plist | |
sed -i "" -e "s|org\.voluntary\.bitmarkets\.helper\.NP|$BUNDLE_ID|g" $PROD_APP/Contents/Frameworks/Bitmarkets\ Helper\ NP.app/Contents/Info.plist | |
sed -i "" -e "s|org\.voluntary\.bitmarkets\.helper|$BUNDLE_ID|g" $PROD_APP/Contents/Frameworks/Bitmarkets\ Helper.app/Contents/Info.plist | |
echo "► Fixed all bundle ids" | |
# ----------------------------------------------------------------------------- | |
# Sign all the items in the ITEMS array - Frameworks, dynamic libraries, .node | |
# ----------------------------------------------------------------------------- | |
for FRAMEWORK in $FRAMEWORKS; | |
do | |
if [[ $FRAMEWORK == *"Helper"* ]] | |
then | |
PACKAGE=${FRAMEWORK%.*} | |
PACKAGE=${PACKAGE#*/*/*/*/} | |
PACKAGERAW=$PACKAGE | |
codesign --force --deep --verify --verbose --entitlements 'child.plist' --sign "$APP_KEY" "$FRAMEWORK/Contents/MacOS/$PACKAGERAW" | |
fi | |
codesign --force --deep --verify --verbose --entitlements 'child.plist' --sign "$APP_KEY" "$FRAMEWORK" | |
RESULT=$? | |
if [[ $RESULT != 0 ]] ; then | |
echo "► Failed to sign '${FRAMEWORK}'" | |
IFS=$SAVED_IFS | |
exit 1 | |
fi | |
done | |
echo "► All frameworks and apps successfully signed" | |
codesign --force --verify --deep --verbose=4 --entitlements 'child.plist' --sign "$APP_KEY" "$PROD_APP/Contents/MacOS/Bitmarkets" | |
RESULT=$? | |
if [[ $RESULT != 0 ]] ; then | |
echo "► Failed to sign Electron executable" | |
IFS=$SAVED_IFS | |
exit 1 | |
fi | |
echo "► Signed the electron executable" | |
codesign --verbose=4 --force --verify -fs "$APP_KEY" -i ${BUNDLE_ID} --entitlements 'parent.plist' "$PROD_APP" | |
echo "► Signed application" | |
codesign --deep-verify -vv --strict "$PROD_APP" | |
codesign -dvvv "$PROD_APP" | |
RESULT=$? | |
if [[ $RESULT != 0 ]] ; then | |
echo "► Failed to sign '${PROD_APP}'" | |
exit 1 | |
fi | |
echo "► Verified app with codesign" | |
chmod -R 777 "$PROD_APP" | |
echo "► Reset app permissions" | |
productbuild --component "$PROD_APP" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" | |
echo "► Built signed .pkg" | |
echo "► ✅ ✅ ✅ ✅ ---------- Build completed and signed ------------- ✅ ✅ ✅ ✅ " | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment