From e60a01483ff048ef07fe7c148a5b8f33ed86d15d Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Fri, 21 Jun 2019 20:30:17 +0300 Subject: macOS DMG bundle, codesign and notarization script --- release/darwin/README.txt | 34 +++++++ release/darwin/blender.applescript | 18 ++++ release/darwin/bundle.sh | 201 +++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 release/darwin/README.txt create mode 100644 release/darwin/blender.applescript create mode 100755 release/darwin/bundle.sh (limited to 'release') diff --git a/release/darwin/README.txt b/release/darwin/README.txt new file mode 100644 index 00000000000..cb4c321f674 --- /dev/null +++ b/release/darwin/README.txt @@ -0,0 +1,34 @@ +Bundling guide: + +Have your signing identity ready, you can check it by running: + +$ secruity find-identity -v -p codesign + +Check that your appleID has two step verification and app specified password generated. https://support.apple.com/en-us/HT204397 +Add it to the login keychain so it won't be in cleartext. + +$ security add-generic-password -a "AC_USERNAME" -w -s "AC_PASSWORD" + +You need then to make sure altool can access your keychain. First time run, there is popup, always allow. Or you can also add it on Keychain Access. + +Then you can make neat bundle using ./bundle.sh by + +$ ./bundle.sh --source --dmg --bundle-id --username --password --codesign + +where: + + directory where built blender.app is + location and name of the final disk image + id on notarization, you choose (for example org.blender.release) + your appleid + your password. having it in keychain, use "@keychain:AC_PASSWORD" + codesigning identity + +Only --sourcedir and --dmg are required flags. + +Example : +$ ./bundle.sh --source /data/build --dmg /data/Blender-2.8-alpha-macOS-10.11.dmg --bundle-id org.blender.alpha --username "foo@mac.com" --password "@keychain:AC_PASSWORD" --codesign AE825E26F12D08B692F360133210AF46F4CF7B97 + + + + diff --git a/release/darwin/blender.applescript b/release/darwin/blender.applescript new file mode 100644 index 00000000000..130dc2eb64c --- /dev/null +++ b/release/darwin/blender.applescript @@ -0,0 +1,18 @@ +tell application "Finder" + tell disk "Blender" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {100, 100, 640, 472} + set theViewOptions to icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 128 + set background picture of theViewOptions to file ".background:background.tif" + set position of item " " of container window to {400, 190} + set position of item "blender.app" of container window to {135, 190} + update without registering applications + delay 5 + close + end tell +end tell diff --git a/release/darwin/bundle.sh b/release/darwin/bundle.sh new file mode 100755 index 00000000000..b61238dc620 --- /dev/null +++ b/release/darwin/bundle.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash + +# create blender distribution dmg + +# check that we have all needed tools + +for i in osascript git codesign hdiutil xcrun ; do + if [ ! -x "$(which ${i})" ]; then + echo "Unable to execute command $i, macOS broken?" + exit 1 + fi +done + +# some defaults settings + +_scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +_volname="Blender" +_tmpdir="$(mktemp -d)" +_tmpdmg="/tmp/blender-tmp.dmg" +BACKGROUND_IMAGE="${_scriptdir}/background.tif" +MOUNT_DIR="/Volumes/${_volname}" + +# handle arguments + +while [[ $# -gt 0 ]]; do + key=$1 + case $key in + -s|--source) + SRC_DIR="$2" + shift + shift + ;; + -d|--dmg) + DEST_DMG="$2" + shift + shift + ;; + -b|--bundle-id) + N_BUNDLE_ID="$2" + shift + shift + ;; + -u|--username) + N_USERNAME="$2" + shift + shift + ;; + -p|--password) + N_PASSWORD="$2" + shift + shift + ;; + -c|--codesign) + C_CERT="$2" + shift + shift + ;; + -h|--help) + echo "Usage:" + echo " $(basename "$0") --source DIR --dmg IMAGENAME " + echo " optional arguments:" + echo " --codesign " + echo " --username " + echo " --password " + echo " --bundle-id " + echo " Check https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow " + exit 1 + ;; + esac +done + +if [ ! -d "${SRC_DIR}/blender.app" ]; then + echo "use --source parameter to set source directory where blender.app can be found" + exit 1 +fi + +if [ -z "${DEST_DMG}" ]; then + echo "use --dmg parameter to set output dmg name" + exit 1 +fi + +# destroy destination dmg if there is any. be warned. + +test -f "${DEST_DMG}" && rm "${DEST_DMG}" +if [ -d "${MOUNT_DIR}" ]; then + echo -n "Ejecting existing blender volume.." + DEV_FILE=$(mount | grep "${MOUNT_DIR}" | awk '{ print $1 }') + diskutil eject "${DEV_FILE}" || exit 1 + echo +fi + +# let's go. + +echo -n "Copying blender.app..." +cp -r "${SRC_DIR}/blender.app" "${_tmpdir}/" || exit 1 +echo + +# Create the disk image + +_ds=$(du -sh ${_tmpdir} | awk -F'[^0-9]*' '$0=$1') # directory size +_is=$(echo "${_ds}" + 200 | bc) # image size with extra 200 ! (why on earth!) for codesign to work +echo +echo -n "Creating disk image of size ${_is}M.." +test -f "${_tmpdmg}" && rm "${_tmpdmg}" +hdiutil create -size "${_is}m" -fs HFS+ -srcfolder "${_tmpdir}" -volname "${_volname}" -format UDRW "${_tmpdmg}" + +echo "Mounting readwrite image..." +hdiutil attach -readwrite -noverify -noautoopen "${_tmpdmg}" + +echo "Setting background picture.." +if ! test -z "${BACKGROUND_IMAGE}"; then + echo "Copying background image ..." + test -d "${MOUNT_DIR}/.background" || mkdir "${MOUNT_DIR}/.background" + BACKGROUND_IMAGE_NAME=$(basename "${BACKGROUND_IMAGE}") + cp "${BACKGROUND_IMAGE}" "${MOUNT_DIR}/.background/${BACKGROUND_IMAGE_NAME}" +fi + +# echo "Creating link to /Applications ..." +ln -s /Applications "${MOUNT_DIR}/Applications" +echo "Renaming Applications to empty string." +mv ${MOUNT_DIR}/Applications "${MOUNT_DIR}/ " + +echo "Running applescript to set folder looks ..." +cat "${_scriptdir}/blender.applescript" | osascript + +echo "Waiting after applescript ..." +sleep 5 + +if [ ! -z "${C_CERT}" ]; then + # codesigning seems to be thingie. all libs and binaries need to be + # signed separately. todo: use some find magic to find those + echo -n "Codesigning..." + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/2.80/python/bin/python3.7m" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/2.80/python/lib/python3.7/site-packages/libextern_draco.dylib" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app/Contents/Resources/lib/libomp.dylib" + codesign --timestamp --options runtime --sign "${C_CERT}" "${MOUNT_DIR}/blender.app" + echo +else + echo "No codesigning cert given, skipping..." +fi + + +echo "Unmounting rw disk image ..." +# need to eject dev files to remove /dev files and free .dmg for converting +DEV_FILE=$(mount | grep "${MOUNT_DIR}" | awk '{ print $1 }') +diskutil eject "${DEV_FILE}" + +sleep 3 + +echo "Compressing disk image ..." +hdiutil convert "${_tmpdmg}" -format UDZO -o "${DEST_DMG}" + +# codesign the dmg + +if [ ! -z "${C_CERT}" ]; then + echo -n "Codesigning dmg..." + codesign --timestamp --force --sign "${C_CERT}" "${DEST_DMG}" + echo +fi + +# cleanup + +rm -rf "${_tmpdir}" +rm "${_tmpdmg}" + +# send notarization +if [ ! -z "${N_USERNAME}" ] && [ ! -z "${N_PASSWORD}" ] && [ ! -z "${N_BUNDLE_ID}" ]; then + echo -n "Sending ${DEST_DMG} for notarization..." + _tmpout=$(mktemp) + xcrun altool --notarize-app -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1 + + # check the request uuid + + _requuid=$(cat "${_tmpout}" | grep "RequestUUID" | awk '{ print $3 }') + echo "RequestUUID: ${_requuid}" + if [ ! -z "${_requuid}" ]; then + echo "Waiting for notarization to be complete.." + for c in {20..0};do + sleep 600 + xcrun altool --notarization-info "${_requuid}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1 + _status=$(cat "${_tmpout}" | grep "Status:" | awk '{ print $2 }') + if [ "${_status}" == "invalid" ]; then + echo "Got invalid notarization!" + break; + fi + + if [ "${_status}" == "success" ]; then + echo -n "Notarization successful! Stapling..." + xcrun stapler staple -v "${DEST_DMG}" + break; + fi + echo "Notarization in progress, waiting..." + done + else + echo "Error getting RequestUUID, notarization unsuccessful" + fi +else + echo "No notarization credentials supplied, skipping..." +fi + +echo "..done. You should have ${DEST_DMG} ready to upload" -- cgit v1.2.3