From 2e258729bbde2e14845e249daaba499d77a6bcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fauconnier?= Date: Fri, 20 May 2022 17:19:33 +0200 Subject: [PATCH] improved release scripts for osx + added scripts for signing and notarizing the app. Each step is now separated (still needs some cleanup) --- .../osx/{release.macx.sh => build.sh} | 93 ++--------- release_scripts/osx/codesign.sh | 104 ++++++++++++ release_scripts/osx/notarize.sh | 147 +++++++++++++++++ release_scripts/osx/package.sh | 155 ++++++++++++++++++ resources/macx/Entitlements.plist | 14 ++ 5 files changed, 437 insertions(+), 76 deletions(-) rename release_scripts/osx/{release.macx.sh => build.sh} (70%) create mode 100755 release_scripts/osx/codesign.sh create mode 100755 release_scripts/osx/notarize.sh create mode 100755 release_scripts/osx/package.sh create mode 100644 resources/macx/Entitlements.plist diff --git a/release_scripts/osx/release.macx.sh b/release_scripts/osx/build.sh similarity index 70% rename from release_scripts/osx/release.macx.sh rename to release_scripts/osx/build.sh index 456b3e90..65f9d7c1 100755 --- a/release_scripts/osx/release.macx.sh +++ b/release_scripts/osx/build.sh @@ -1,4 +1,4 @@ -:#!/bin/bash +#!/bin/bash # -------------------------------------------------------------------- # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -40,16 +40,21 @@ function notify { if [ -x "$GROWLNOTIFY" ]; then $GROWLNOTIFY --name OpenBoard-build --iconpath /Developer/Applications/Xcode.app --message "$1" "OpenBoard" fi - printf "\033[32m--->\033[0m $1\n" + printf "\033[48;5;120m--->\033[0m $1\n" } -function abort { - printf "\033[31merror:\033[0m $1\n" - exit 1 +function warn { + printf "\033[48;5;178m--->\033[0m $1\n" } -function warn { - abort "$1" +function error +{ + printf "\033[48;5;160;38;5;15m--->\033[0m $1\n" +} + +function abort { + error "$1" + exit 1 } function checkExecutable { @@ -164,21 +169,7 @@ VERSION=`cat "$BUILD_DIR/version"` if [ ! -f "$BUILD_DIR/version" ]; then echo "version not found" exit 1 -#else -# notify "Tagging ..." -# LAST_COMMITED_VERSION="`git describe $(git rev-list --tags --max-count=1)`" -# if [ "v$VERSION" != "$LAST_COMMITED_VERSION" ]; then -# echo creating a tag with the version $VERSION -# git tag -a "v$VERSION" -m "Generated setup for v$VERSION" -# git push origin --tags -# fi fi - -#if [ $? != 0 ]; then -# abort "compilation failed" -#fi - -DMG="$APPLICATION_NAME.dmg" VOLUME="/Volumes/$APPLICATION_NAME" APP="$PRODUCT_DIR/$APPLICATION_NAME.app" @@ -204,61 +195,11 @@ notify "Extracting debug information ..." $DSYMUTIL "$APP/Contents/MacOS/$APPLICATION_NAME" -o "$DSYM" $STRIP -S "$APP/Contents/MacOS/$APPLICATION_NAME" -if [ "$1" == "pkg" ]; then - BASE_ICEBERG_CONFIG_FILE="$SCRIPT_PATH/$APPLICATION_NAME.packproj" - #copy the standard file for working with - ICEBERG_CONFIG_FILE="$APPLICATION_NAME-working.packproj" - cp -r $BASE_ICEBERG_CONFIG_FILE $ICEBERG_CONFIG_FILE - # set version information - $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Description:International:IFPkgDescriptionVersion $VERSION" "$ICEBERG_CONFIG_FILE" - $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Display\ Information:CFBundleShortVersionString $VERSION" "$ICEBERG_CONFIG_FILE" - $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Version:IFMajorVersion `echo $VERSION | awk 'BEGIN { FS = "." }; { print $1 }'`" "$ICEBERG_CONFIG_FILE" - $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Version:IFMinorVersion `echo $VERSION | awk 'BEGIN { FS = "." }; { print $2 }'`" "$ICEBERG_CONFIG_FILE" - - - PRODUCT_DIR="install/mac/" - - if [ ! -d "${PRODUCT_DIR}" ]; then - mkdir -p "${PRODUCT_DIR}" - fi - $ICEBERG $ICEBERG_CONFIG_FILE - - #clean up mess - rm -rf $ICEBERG_CONFIG_FILE - - exit 0 -fi - -notify "Creating dmg ..." -umount "$VOLUME" 2> /dev/null -$DMGUTIL --open --volume="$APPLICATION_NAME" "$DMG" - -#cp *.pdf "$VOLUME" -cp -R "$APP" "$VOLUME" -ln -s /Applications "$VOLUME" - -$DMGUTIL --set --iconsize=96 --toolbar=false --icon=resources/macx/OpenBoard.icns "$VOLUME" -$DMGUTIL --set --x=20 --y=60 --width=580 --height=440 "$VOLUME" -$DMGUTIL --set --x=180 --y=120 "$VOLUME/`basename \"$APP\"`" -$DMGUTIL --set --x=400 --y=120 "$VOLUME/Applications" - -$DMGUTIL --close --volume="$APPLICATION_NAME" "$DMG" - -notify "$APPLICATION_NAME is built" - -PRODUCT_DIR="install/mac/" - -if [ ! -d "${PRODUCT_DIR}" ]; then - mkdir -p "${PRODUCT_DIR}" -fi - - -if [ "$1" == "1010" ]; then - mv "$DMG" "${PRODUCT_DIR}/OpenBoard_for_1010.dmg" -else - mv "$DMG" "${PRODUCT_DIR}" -fi - +notify "$APPLICATION_NAME is now built. You can now sign the application using the script 'codesign.sh'." +notify "Usage : sudo ./codesign.sh \"Developer ID Application: ...\"" +notify "You can also ignore signing step if you don't intend to distribute this version" +notify "If so, you can directly package OpenBoard using the script 'package.sh'" +notify "Usage : sudo ./package.sh" exit 0 diff --git a/release_scripts/osx/codesign.sh b/release_scripts/osx/codesign.sh new file mode 100755 index 00000000..1219fa3b --- /dev/null +++ b/release_scripts/osx/codesign.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# -------------------------------------------------------------------- +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# --------------------------------------------------------------------- + +SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$SCRIPT_PATH/../.." + +IDENTITY=$1 + +CODESIGN=/usr/bin/codesign + +BUILD_DIR="$PROJECT_ROOT/build/macx/release" +PRODUCT_DIR="$BUILD_DIR/product" +RESOURCES_DIR="$PROJECT_ROOT/resources" +MACX_RESOURCES_DIR="$RESOURCES_DIR/macx" +INSTALL_DIR="$PROJECT_ROOT/install/mac" + +APPLICATION_NAME="OpenBoard" +APPLICATION_DOT_APP="$APPLICATION_NAME.app" +APPLICATION_DIR="$PRODUCT_DIR/$APPLICATION_DOT_APP" +APPLICATION_CONTENTS_DIR="$APPLICATION_DIR/Contents" +APPLICATION_RESOURCES_DIR="$APPLICATION_CONTENTS_DIR/Resources" + +IMPORTER_NAME="OpenBoardImporter" +IMPORTER_DOT_APP="$IMPORTER_NAME.app" +IMPORTER_DIR="$APPLICATION_RESOURCES_DIR/$IMPORTER_DOT_APP" + + +function notify { + GROWLNOTIFY=`which growlnotify` + if [ -x "$GROWLNOTIFY" ]; then + $GROWLNOTIFY --name OpenBoard-build --iconpath /Developer/Applications/Xcode.app --message "$1" "OpenBoard" + fi + printf "\033[48;5;120m--->\033[0m $1\n" +} + +function warn { + printf "\033[48;5;178m--->\033[0m $1\n" +} + +function error +{ + printf "\033[48;5;160;38;5;15m--->\033[0m $1\n" +} + +function abort { + error "$1" + exit 1 +} + +function checkExecutable { + if [ ! -x "$1" ]; then + abort "$1 not found" + fi +} + +checkExecutable $CODESIGN + +function signImporter +{ + notify "signing $IMPORTER_NAME..." + if [ ! -e ${IMPORTER_DIR} ]; then + abort "${IMPORTER_DIR} not found" + fi + + cd $APPLICATION_RESOURCES_DIR + + $CODESIGN --force --deep -o runtime --timestamp --verbose=4 -s "$IDENTITY" --digest-algorithm=sha1,sha256 "$IMPORTER_DOT_APP" + cd - +} + +function signOpenBoard +{ + notify "signing $APPLICATION_NAME..." + if [ ! -e ${APPLICATION_DIR} ]; then + abort "${APPLICATION_DIR} not found" + fi + + cd $PRODUCT_DIR + + $CODESIGN --force --deep -o runtime --timestamp --entitlements "$MACX_RESOURCES_DIR/Entitlements.plist" --verbose=4 -s "$IDENTITY" --digest-algorithm=sha1,sha256 "$APPLICATION_DOT_APP" + cd - +} + +signImporter + +signOpenBoard + +notify "$APPLICATION_NAME is now signed. You can now package OpenBoard using the script 'package.sh'" + +exit 0 + diff --git a/release_scripts/osx/notarize.sh b/release_scripts/osx/notarize.sh new file mode 100755 index 00000000..fa4b6a39 --- /dev/null +++ b/release_scripts/osx/notarize.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# -------------------------------------------------------------------- +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# --------------------------------------------------------------------- + +SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$SCRIPT_PATH/../.." + + +APPLICATION_NAME="OpenBoard" +BASE_QT_DIR=~/Qt/5.15.2/clang_64 +# Executables +QMAKE=$BASE_QT_DIR/bin/qmake +MACDEPLOYQT=$BASE_QT_DIR/bin/macdeployqt +CODESIGN=/usr/bin/codesign +DMGUTIL="$PROJECT_ROOT/release_scripts/osx/refnum/dmgutil/dmgutil.pl" +DSYMUTIL=/usr/bin/dsymutil +STRIP=/usr/bin/strip +PLISTBUDDY=/usr/libexec/PlistBuddy +ICEBERG=/usr/local/bin/freeze +LRELEASE=$BASE_QT_DIR/bin/lrelease +USER=$1 + +# Directories +BUILD_DIR="$PROJECT_ROOT/build/macx/release" +PRODUCT_DIR="$BUILD_DIR/product" +RESOURCES_DIR="$PROJECT_ROOT/resources" +MACX_RESOURCES_DIR="$RESOURCES_DIR/macx" +BASE_QT_TRANSLATIONS_DIRECTORY=$BASE_QT_DIR/translations +INSTALL_DIR="$PROJECT_ROOT/install/mac" + +function notify { + GROWLNOTIFY=`which growlnotify` + if [ -x "$GROWLNOTIFY" ]; then + $GROWLNOTIFY --name OpenBoard-build --iconpath /Developer/Applications/Xcode.app --message "$1" "OpenBoard" + fi + printf "\033[48;5;120m--->\033[0m $1\n" +} + +function warn { + printf "\033[48;5;178m--->\033[0m $1\n" +} + +function error +{ + printf "\033[48;5;160;38;5;15m--->\033[0m $1\n" +} + +function abort { + error "$1" + exit 1 +} + +function checkExecutable { + if [ ! -x "$1" ]; then + abort "$1 not found" + fi +} + +notify "================================================" +notify "=============== NOTARIZATION ===================" +notify "================================================" +read -s -p "Password for $USER is required: " PASSWORD +printf "\n" + +cd $INSTALL_DIR; + +notify "================================================" +notify "Submitting $APPLICATION_NAME for notarization..." +notify "================================================" + +NOTARIZE_APP_OUTPUT=$(2>&1 xcrun altool --notarize-app -f OpenBoard.dmg --primary-bundle-id ch.openboard.id -u "$USER" -p "$PASSWORD") +SUBMISSION_ID=$(echo "$NOTARIZE_APP_OUTPUT" | grep "RequestUUID" | sed -Ee "s|.*= (.*)$|\1|") + + +if [[ "$SUBMISSION_ID" == "" ]]; then + NOTARIZE_APP_ERROR_LOG_NAME="notarization-submission-error.log" + NOTARIZE_APP_ERROR_LOG_PATH="$SCRIPT_PATH/$NOTARIZE_APP_ERROR_LOG_NAME" + + echo "$NOTARIZE_APP_OUTPUT" > "$NOTARIZE_APP_ERROR_LOG_PATH" + + warn "================================================" + warn "Submission of $APPLICATION_NAME failed !" + warn "See $NOTARIZE_APP_ERROR_LOG_NAME for details." + warn "================================================" + + abort "$APPLICATION_NAME notarization failed" +else + NOTARIZE_APP_SUCCESS_LOG_NAME="notarization-submission-success.log" + NOTARIZE_APP_SUCCESS_LOG_PATH="$SCRIPT_PATH/$NOTARIZE_APP_SUCCESS_LOG_NAME" + + echo "$OUTPUT" > "$NOTARIZE_APP_SUCCESS_LOG_PATH" + + notify "================================================" + notify "Submission of $APPLICATION_NAME succeed." + notify "See $NOTARIZE_APP_SUCCESS_LOG_NAME for details." + notify "================================================" + + notify "================================================" + notify "Checking status of notarization (RequestUUID = $SUBMISSION_ID)" + notify "================================================" + + while true; do + NOTARIZATION_INFO_OUTPUT=$(2>&1 xcrun altool --notarization-info "$SUBMISSION_ID" -u "$USER" -p "$PASSWORD") + STATUS=$(echo "$NOTARIZATION_INFO_OUTPUT" | grep "Status:" | sed -Ee "s|.*: (.*)$|\1|" ) + notify "notarization status: $STATUS" + if [[ "$STATUS" != "in progress" ]]; then + break + fi + sleep 30 + done + + if [[ $STATUS == "success" ]]; then + NOTARIZATION_SUCCESS_LOG_NAME="notarization-success.log" + NOTARIZATION_SUCCESS_LOG="$SCRIPT_PATH/$NOTARIZATION_SUCCESS_LOG_NAME" + echo "$NOTARIZATION_INFO_OUTPUT" > "$NOTARIZATION_SUCCESS_LOG" + + notify "================================================" + notify "$APPLICATION_NAME was notarized sucessfully. You can now distribute it." + notify "See $NOTARIZATION_SUCCESS_LOG_NAME for details." + notify "================================================" + else + NOTARIZATION_ERROR_LOG_NAME="notarization-error.log" + NOTARIZATION_ERROR_LOG="$SCRIPT_PATH/$NOTARIZATION_ERROR_LOG_NAME" + echo "$NOTARIZATION_INFO_OUTPUT" > "$NOTARIZATION_ERROR_LOG" + + warn "================================================" + warn "$APPLICATION_NAME could not be notarized." + warn "See $NOTARIZATION_ERROR_LOG_NAME for details." + warn "================================================" + + abort "$APPLICATION_NAME notarization failed" + fi +fi +exit 0 + diff --git a/release_scripts/osx/package.sh b/release_scripts/osx/package.sh new file mode 100755 index 00000000..38079929 --- /dev/null +++ b/release_scripts/osx/package.sh @@ -0,0 +1,155 @@ +#!/bin/bash +# -------------------------------------------------------------------- +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# --------------------------------------------------------------------- + +SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$SCRIPT_PATH/../.." + + +APPLICATION_NAME="OpenBoard" +BASE_QT_DIR=~/Qt/5.15.2/clang_64 +# Executables +QMAKE=$BASE_QT_DIR/bin/qmake +MACDEPLOYQT=$BASE_QT_DIR/bin/macdeployqt +DMGUTIL="$PROJECT_ROOT/release_scripts/osx/refnum/dmgutil/dmgutil.pl" +DSYMUTIL=/usr/bin/dsymutil +STRIP=/usr/bin/strip +PLISTBUDDY=/usr/libexec/PlistBuddy +ICEBERG=/usr/local/bin/freeze +LRELEASE=$BASE_QT_DIR/bin/lrelease + +# Directories +BUILD_DIR="$PROJECT_ROOT/build/macx/release" +PRODUCT_DIR="$BUILD_DIR/product" +BASE_QT_TRANSLATIONS_DIRECTORY=$BASE_QT_DIR/translations + + +function notify { + GROWLNOTIFY=`which growlnotify` + if [ -x "$GROWLNOTIFY" ]; then + $GROWLNOTIFY --name OpenBoard-build --iconpath /Developer/Applications/Xcode.app --message "$1" "OpenBoard" + fi + printf "\033[48;5;120m--->\033[0m $1\n" +} + +function warn { + printf "\033[48;5;178m--->\033[0m $1\n" +} + +function error +{ + printf "\033[48;5;160;38;5;15m--->\033[0m $1\n" +} + +function abort { + error "$1" + exit 1 +} + +function checkExecutable { + if [ ! -x "$1" ]; then + abort "$1 not found" + fi +} + +trap "defaults write org.oe-f.OpenBoard.release Running -bool NO" EXIT + +notify "Running OpenBoard release script (`date`)" + +cd $PROJECT_ROOT + +script_is_running=`defaults read org.oe-f.OpenBoard.release Running 2>/dev/null` +if [[ $? -eq 0 ]] && [[ "$script_is_running" = "1" ]]; then + trap EXIT + abort "another release script already running" +fi +defaults write org.oe-f.OpenBoard.release Running -bool YES + +# Check for executables +checkExecutable "$QMAKE" +checkExecutable "$MACDEPLOYQT" +checkExecutable "$DMGUTIL" +checkExecutable "$DSYMUTIL" +checkExecutable "$STRIP" +checkExecutable "$PLISTBUDDY" +checkExecutable "$ICEBERG" +checkExecutable "$LRELEASE" + +DMG="$APPLICATION_NAME.dmg" + +VOLUME="/Volumes/$APPLICATION_NAME" +APP="$PRODUCT_DIR/$APPLICATION_NAME.app" +DSYM_NAME="$APPLICATION_NAME (r$SVN_REVISION).dSYM" +DSYM="$PRODUCT_DIR/$DSYM_NAME" +GSYM_i386="$PRODUCT_DIR/$APPLICATION_NAME i386.sym" +INFO_PLIST="$APP/Contents/Info.plist" + +if [ "$1" == "pkg" ]; then + BASE_ICEBERG_CONFIG_FILE="$SCRIPT_PATH/$APPLICATION_NAME.packproj" + #copy the standard file for working with + ICEBERG_CONFIG_FILE="$APPLICATION_NAME-working.packproj" + cp -r $BASE_ICEBERG_CONFIG_FILE $ICEBERG_CONFIG_FILE + # set version information + $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Description:International:IFPkgDescriptionVersion $VERSION" "$ICEBERG_CONFIG_FILE" + $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Display\ Information:CFBundleShortVersionString $VERSION" "$ICEBERG_CONFIG_FILE" + $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Version:IFMajorVersion `echo $VERSION | awk 'BEGIN { FS = "." }; { print $1 }'`" "$ICEBERG_CONFIG_FILE" + $PLISTBUDDY -c "Set :Hierarchy:Attributes:Settings:Version:IFMinorVersion `echo $VERSION | awk 'BEGIN { FS = "." }; { print $2 }'`" "$ICEBERG_CONFIG_FILE" + + + PRODUCT_DIR="install/mac/" + + if [ ! -d "${PRODUCT_DIR}" ]; then + mkdir -p "${PRODUCT_DIR}" + fi + $ICEBERG $ICEBERG_CONFIG_FILE + + #clean up mess + rm -rf $ICEBERG_CONFIG_FILE + + exit 0 +fi + +notify "Creating dmg ..." +umount "$VOLUME" 2> /dev/null +$DMGUTIL --open --volume="$APPLICATION_NAME" "$DMG" + +#cp *.pdf "$VOLUME" +cp -R "$APP" "$VOLUME" +ln -s /Applications "$VOLUME" + +$DMGUTIL --set --iconsize=96 --toolbar=false --icon=resources/macx/OpenBoard.icns "$VOLUME" +$DMGUTIL --set --x=20 --y=60 --width=580 --height=440 "$VOLUME" +$DMGUTIL --set --x=180 --y=120 "$VOLUME/`basename \"$APP\"`" +$DMGUTIL --set --x=400 --y=120 "$VOLUME/Applications" + +$DMGUTIL --close --volume="$APPLICATION_NAME" "$DMG" + +PRODUCT_DIR="install/mac/" + +if [ ! -d "${PRODUCT_DIR}" ]; then + mkdir -p "${PRODUCT_DIR}" +fi + + +if [ "$1" == "1010" ]; then + mv "$DMG" "${PRODUCT_DIR}/OpenBoard_for_1010.dmg" +else + mv "$DMG" "${PRODUCT_DIR}" +fi + +notify "$APPLICATION_NAME is now packaged. You can submit this dmg file to notarization using notarize.sh" + +exit 0 + diff --git a/resources/macx/Entitlements.plist b/resources/macx/Entitlements.plist new file mode 100644 index 00000000..21f2b3fe --- /dev/null +++ b/resources/macx/Entitlements.plist @@ -0,0 +1,14 @@ + + + + + com.apple.security.automation.apple-events + + com.apple.security.cs.disable-library-validation + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + +