2019-06-21 17:30:17 +00:00
|
|
|
#!/usr/bin/env bash
|
2019-06-22 13:51:35 +00:00
|
|
|
#
|
|
|
|
# Script to create a macOS dmg file for Blender builds, including code
|
|
|
|
# signing and notarization for releases.
|
2019-06-21 17:30:17 +00:00
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Check that we have all needed tools.
|
2019-06-21 17:30:17 +00:00
|
|
|
for i in osascript git codesign hdiutil xcrun ; do
|
|
|
|
if [ ! -x "$(which ${i})" ]; then
|
2019-06-22 13:51:35 +00:00
|
|
|
echo "Unable to execute command $i, macOS broken?"
|
|
|
|
exit 1
|
2019-06-21 17:30:17 +00:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Defaults settings.
|
|
|
|
_script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
|
|
_volume_name="Blender"
|
|
|
|
_tmp_dir="$(mktemp -d)"
|
|
|
|
_tmp_dmg="/tmp/blender-tmp.dmg"
|
|
|
|
_background_image="${_script_dir}/background.tif"
|
|
|
|
_mount_dir="/Volumes/${_volume_name}"
|
2019-07-15 12:18:42 +00:00
|
|
|
_entitlements="${_script_dir}/entitlements.plist"
|
2019-06-21 17:30:17 +00:00
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Handle arguments.
|
2019-06-21 17:30:17 +00:00
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
key=$1
|
|
|
|
case $key in
|
2019-06-22 13:51:35 +00:00
|
|
|
-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
|
|
|
|
;;
|
2019-08-31 12:24:52 +00:00
|
|
|
--background-image)
|
|
|
|
_background_image="$2"
|
|
|
|
shift
|
|
|
|
shift
|
|
|
|
;;
|
2019-06-22 13:51:35 +00:00
|
|
|
-h|--help)
|
|
|
|
echo "Usage:"
|
|
|
|
echo " $(basename "$0") --source DIR --dmg IMAGENAME "
|
|
|
|
echo " optional arguments:"
|
|
|
|
echo " --codesign <certname>"
|
|
|
|
echo " --username <username>"
|
|
|
|
echo " --password <password>"
|
|
|
|
echo " --bundle-id <bundleid>"
|
|
|
|
echo " Check https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow "
|
|
|
|
exit 1
|
|
|
|
;;
|
2019-06-21 17:30:17 +00:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2019-06-21 16:12:00 +00:00
|
|
|
if [ ! -d "${SRC_DIR}/Blender.app" ]; then
|
|
|
|
echo "use --source parameter to set source directory where Blender.app can be found"
|
2019-06-21 17:30:17 +00:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "${DEST_DMG}" ]; then
|
|
|
|
echo "use --dmg parameter to set output dmg name"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Destroy destination dmg if there is any.
|
2019-06-21 17:30:17 +00:00
|
|
|
test -f "${DEST_DMG}" && rm "${DEST_DMG}"
|
2019-06-22 13:51:35 +00:00
|
|
|
if [ -d "${_mount_dir}" ]; then
|
2019-06-21 17:30:17 +00:00
|
|
|
echo -n "Ejecting existing blender volume.."
|
2019-06-22 13:51:35 +00:00
|
|
|
DEV_FILE=$(mount | grep "${_mount_dir}" | awk '{ print $1 }')
|
2019-06-21 17:30:17 +00:00
|
|
|
diskutil eject "${DEV_FILE}" || exit 1
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Copy dmg contents.
|
2019-06-21 16:12:00 +00:00
|
|
|
echo -n "Copying Blender.app..."
|
2019-06-22 13:51:35 +00:00
|
|
|
cp -r "${SRC_DIR}/Blender.app" "${_tmp_dir}/" || exit 1
|
2019-06-21 17:30:17 +00:00
|
|
|
echo
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Create the disk image.
|
|
|
|
_directory_size=$(du -sh ${_tmp_dir} | awk -F'[^0-9]*' '$0=$1')
|
2019-12-04 15:27:16 +00:00
|
|
|
_image_size=$(echo "${_directory_size}" + 400 | bc) # extra 400 need for codesign to work (why on earth?)
|
2019-06-21 17:30:17 +00:00
|
|
|
|
|
|
|
echo
|
2019-06-22 13:51:35 +00:00
|
|
|
echo -n "Creating disk image of size ${_image_size}M.."
|
|
|
|
test -f "${_tmp_dmg}" && rm "${_tmp_dmg}"
|
2020-01-22 10:11:58 +00:00
|
|
|
hdiutil create -size "${_image_size}m" -fs HFS+ -srcfolder "${_tmp_dir}" -volname "${_volume_name}" -format UDRW "${_tmp_dmg}" -mode 755
|
2019-06-21 17:30:17 +00:00
|
|
|
|
|
|
|
echo "Mounting readwrite image..."
|
2019-06-22 13:51:35 +00:00
|
|
|
hdiutil attach -readwrite -noverify -noautoopen "${_tmp_dmg}"
|
2019-06-21 17:30:17 +00:00
|
|
|
|
|
|
|
echo "Setting background picture.."
|
2019-06-22 13:51:35 +00:00
|
|
|
if ! test -z "${_background_image}"; then
|
2019-06-21 17:30:17 +00:00
|
|
|
echo "Copying background image ..."
|
2019-06-22 13:51:35 +00:00
|
|
|
test -d "${_mount_dir}/.background" || mkdir "${_mount_dir}/.background"
|
|
|
|
_background_image_NAME=$(basename "${_background_image}")
|
|
|
|
cp "${_background_image}" "${_mount_dir}/.background/${_background_image_NAME}"
|
2019-06-21 17:30:17 +00:00
|
|
|
fi
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
echo "Creating link to /Applications ..."
|
|
|
|
ln -s /Applications "${_mount_dir}/Applications"
|
2019-06-21 17:30:17 +00:00
|
|
|
echo "Renaming Applications to empty string."
|
2019-06-22 13:51:35 +00:00
|
|
|
mv ${_mount_dir}/Applications "${_mount_dir}/ "
|
2019-06-21 17:30:17 +00:00
|
|
|
|
|
|
|
echo "Running applescript to set folder looks ..."
|
2019-06-22 13:51:35 +00:00
|
|
|
cat "${_script_dir}/blender.applescript" | osascript
|
2019-06-21 17:30:17 +00:00
|
|
|
|
|
|
|
echo "Waiting after applescript ..."
|
|
|
|
sleep 5
|
|
|
|
|
|
|
|
if [ ! -z "${C_CERT}" ]; then
|
2019-06-22 13:51:35 +00:00
|
|
|
# Codesigning requires all libs and binaries to be signed separately.
|
2019-07-12 12:44:16 +00:00
|
|
|
echo -n "Codesigning Python"
|
|
|
|
for f in $(find "${_mount_dir}/Blender.app/Contents/Resources" -name "python*"); do
|
2019-07-12 16:58:44 +00:00
|
|
|
if [ -x ${f} ] && [ ! -d ${f} ]; then
|
|
|
|
codesign --remove-signature "${f}"
|
2019-07-15 12:18:42 +00:00
|
|
|
codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${f}"
|
2019-07-12 16:58:44 +00:00
|
|
|
fi
|
2019-07-12 12:44:16 +00:00
|
|
|
done
|
|
|
|
echo ; echo -n "Codesigning .dylib and .so libraries"
|
|
|
|
for f in $(find "${_mount_dir}/Blender.app" -name "*.dylib" -o -name "*.so"); do
|
2019-07-12 16:58:44 +00:00
|
|
|
codesign --remove-signature "${f}"
|
2019-07-15 12:18:42 +00:00
|
|
|
codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${f}"
|
2019-07-12 12:44:16 +00:00
|
|
|
done
|
|
|
|
echo ; echo -n "Codesigning Blender.app"
|
2019-07-12 16:58:44 +00:00
|
|
|
codesign --remove-signature "${_mount_dir}/Blender.app"
|
2019-07-15 12:18:42 +00:00
|
|
|
codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${_mount_dir}/Blender.app"
|
2019-06-21 17:30:17 +00:00
|
|
|
echo
|
|
|
|
else
|
|
|
|
echo "No codesigning cert given, skipping..."
|
|
|
|
fi
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Need to eject dev files to remove /dev files and free .dmg for converting
|
2019-06-21 17:30:17 +00:00
|
|
|
echo "Unmounting rw disk image ..."
|
2019-06-22 13:51:35 +00:00
|
|
|
DEV_FILE=$(mount | grep "${_mount_dir}" | awk '{ print $1 }')
|
2019-06-21 17:30:17 +00:00
|
|
|
diskutil eject "${DEV_FILE}"
|
|
|
|
|
|
|
|
sleep 3
|
|
|
|
|
|
|
|
echo "Compressing disk image ..."
|
2019-06-22 13:51:35 +00:00
|
|
|
hdiutil convert "${_tmp_dmg}" -format UDZO -o "${DEST_DMG}"
|
2019-06-21 17:30:17 +00:00
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Codesign the dmg
|
2019-06-21 17:30:17 +00:00
|
|
|
if [ ! -z "${C_CERT}" ]; then
|
|
|
|
echo -n "Codesigning dmg..."
|
|
|
|
codesign --timestamp --force --sign "${C_CERT}" "${DEST_DMG}"
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Cleanup
|
|
|
|
rm -rf "${_tmp_dir}"
|
|
|
|
rm "${_tmp_dmg}"
|
2019-06-21 17:30:17 +00:00
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Notarize
|
2019-06-21 17:30:17 +00:00
|
|
|
if [ ! -z "${N_USERNAME}" ] && [ ! -z "${N_PASSWORD}" ] && [ ! -z "${N_BUNDLE_ID}" ]; then
|
2019-06-22 13:51:35 +00:00
|
|
|
# Send to Apple
|
2019-12-04 15:27:16 +00:00
|
|
|
echo "Sending ${DEST_DMG} for notarization..."
|
2019-06-21 17:30:17 +00:00
|
|
|
_tmpout=$(mktemp)
|
2019-12-04 15:27:16 +00:00
|
|
|
echo xcrun altool --notarize-app --verbose -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}"
|
|
|
|
xcrun altool --notarize-app --verbose -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1
|
2019-06-21 17:30:17 +00:00
|
|
|
|
2019-06-22 13:51:35 +00:00
|
|
|
# Parse request uuid
|
2019-06-21 17:30:17 +00:00
|
|
|
_requuid=$(cat "${_tmpout}" | grep "RequestUUID" | awk '{ print $3 }')
|
|
|
|
echo "RequestUUID: ${_requuid}"
|
|
|
|
if [ ! -z "${_requuid}" ]; then
|
2019-06-22 13:51:35 +00:00
|
|
|
# Wait for Apple to confirm notarization is complete
|
|
|
|
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
|
2019-06-21 17:30:17 +00:00
|
|
|
else
|
2019-12-04 15:27:16 +00:00
|
|
|
cat ${_tmpout}
|
2019-06-22 13:51:35 +00:00
|
|
|
echo "Error getting RequestUUID, notarization unsuccessful"
|
2019-06-21 17:30:17 +00:00
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "No notarization credentials supplied, skipping..."
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "..done. You should have ${DEST_DMG} ready to upload"
|