bundle.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/env bash
  2. #
  3. # Script to create a macOS dmg file for Blender builds, including code
  4. # signing and notarization for releases.
  5. # Check that we have all needed tools.
  6. for i in osascript git codesign hdiutil xcrun ; do
  7. if [ ! -x "$(which ${i})" ]; then
  8. echo "Unable to execute command $i, macOS broken?"
  9. exit 1
  10. fi
  11. done
  12. # Defaults settings.
  13. _script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
  14. _volume_name="Blender"
  15. _tmp_dir="$(mktemp -d)"
  16. _tmp_dmg="/tmp/blender-tmp.dmg"
  17. _background_image="${_script_dir}/background.tif"
  18. _mount_dir="/Volumes/${_volume_name}"
  19. _entitlements="${_script_dir}/entitlements.plist"
  20. # Handle arguments.
  21. while [[ $# -gt 0 ]]; do
  22. key=$1
  23. case $key in
  24. -s|--source)
  25. SRC_DIR="$2"
  26. shift
  27. shift
  28. ;;
  29. -d|--dmg)
  30. DEST_DMG="$2"
  31. shift
  32. shift
  33. ;;
  34. -b|--bundle-id)
  35. N_BUNDLE_ID="$2"
  36. shift
  37. shift
  38. ;;
  39. -u|--username)
  40. N_USERNAME="$2"
  41. shift
  42. shift
  43. ;;
  44. -p|--password)
  45. N_PASSWORD="$2"
  46. shift
  47. shift
  48. ;;
  49. -c|--codesign)
  50. C_CERT="$2"
  51. shift
  52. shift
  53. ;;
  54. -h|--help)
  55. echo "Usage:"
  56. echo " $(basename "$0") --source DIR --dmg IMAGENAME "
  57. echo " optional arguments:"
  58. echo " --codesign <certname>"
  59. echo " --username <username>"
  60. echo " --password <password>"
  61. echo " --bundle-id <bundleid>"
  62. echo " Check https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow "
  63. exit 1
  64. ;;
  65. esac
  66. done
  67. if [ ! -d "${SRC_DIR}/Blender.app" ]; then
  68. echo "use --source parameter to set source directory where Blender.app can be found"
  69. exit 1
  70. fi
  71. if [ -z "${DEST_DMG}" ]; then
  72. echo "use --dmg parameter to set output dmg name"
  73. exit 1
  74. fi
  75. # Destroy destination dmg if there is any.
  76. test -f "${DEST_DMG}" && rm "${DEST_DMG}"
  77. if [ -d "${_mount_dir}" ]; then
  78. echo -n "Ejecting existing blender volume.."
  79. DEV_FILE=$(mount | grep "${_mount_dir}" | awk '{ print $1 }')
  80. diskutil eject "${DEV_FILE}" || exit 1
  81. echo
  82. fi
  83. # Copy dmg contents.
  84. echo -n "Copying Blender.app..."
  85. cp -r "${SRC_DIR}/Blender.app" "${_tmp_dir}/" || exit 1
  86. echo
  87. # Create the disk image.
  88. _directory_size=$(du -sh ${_tmp_dir} | awk -F'[^0-9]*' '$0=$1')
  89. _image_size=$(echo "${_directory_size}" + 200 | bc) # extra 200 need for codesign to work (why on earth?)
  90. echo
  91. echo -n "Creating disk image of size ${_image_size}M.."
  92. test -f "${_tmp_dmg}" && rm "${_tmp_dmg}"
  93. hdiutil create -size "${_image_size}m" -fs HFS+ -srcfolder "${_tmp_dir}" -volname "${_volume_name}" -format UDRW "${_tmp_dmg}"
  94. echo "Mounting readwrite image..."
  95. hdiutil attach -readwrite -noverify -noautoopen "${_tmp_dmg}"
  96. echo "Setting background picture.."
  97. if ! test -z "${_background_image}"; then
  98. echo "Copying background image ..."
  99. test -d "${_mount_dir}/.background" || mkdir "${_mount_dir}/.background"
  100. _background_image_NAME=$(basename "${_background_image}")
  101. cp "${_background_image}" "${_mount_dir}/.background/${_background_image_NAME}"
  102. fi
  103. echo "Creating link to /Applications ..."
  104. ln -s /Applications "${_mount_dir}/Applications"
  105. echo "Renaming Applications to empty string."
  106. mv ${_mount_dir}/Applications "${_mount_dir}/ "
  107. echo "Running applescript to set folder looks ..."
  108. cat "${_script_dir}/blender.applescript" | osascript
  109. echo "Waiting after applescript ..."
  110. sleep 5
  111. if [ ! -z "${C_CERT}" ]; then
  112. # Codesigning requires all libs and binaries to be signed separately.
  113. echo -n "Codesigning Python"
  114. for f in $(find "${_mount_dir}/Blender.app/Contents/Resources" -name "python*"); do
  115. if [ -x ${f} ] && [ ! -d ${f} ]; then
  116. codesign --remove-signature "${f}"
  117. codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${f}"
  118. fi
  119. done
  120. echo ; echo -n "Codesigning .dylib and .so libraries"
  121. for f in $(find "${_mount_dir}/Blender.app" -name "*.dylib" -o -name "*.so"); do
  122. codesign --remove-signature "${f}"
  123. codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${f}"
  124. done
  125. echo ; echo -n "Codesigning Blender.app"
  126. codesign --remove-signature "${_mount_dir}/Blender.app"
  127. codesign --timestamp --options runtime --entitlements="${_entitlements}" --sign "${C_CERT}" "${_mount_dir}/Blender.app"
  128. echo
  129. else
  130. echo "No codesigning cert given, skipping..."
  131. fi
  132. # Need to eject dev files to remove /dev files and free .dmg for converting
  133. echo "Unmounting rw disk image ..."
  134. DEV_FILE=$(mount | grep "${_mount_dir}" | awk '{ print $1 }')
  135. diskutil eject "${DEV_FILE}"
  136. sleep 3
  137. echo "Compressing disk image ..."
  138. hdiutil convert "${_tmp_dmg}" -format UDZO -o "${DEST_DMG}"
  139. # Codesign the dmg
  140. if [ ! -z "${C_CERT}" ]; then
  141. echo -n "Codesigning dmg..."
  142. codesign --timestamp --force --sign "${C_CERT}" "${DEST_DMG}"
  143. echo
  144. fi
  145. # Cleanup
  146. rm -rf "${_tmp_dir}"
  147. rm "${_tmp_dmg}"
  148. # Notarize
  149. if [ ! -z "${N_USERNAME}" ] && [ ! -z "${N_PASSWORD}" ] && [ ! -z "${N_BUNDLE_ID}" ]; then
  150. # Send to Apple
  151. echo -n "Sending ${DEST_DMG} for notarization..."
  152. _tmpout=$(mktemp)
  153. echo xcrun altool --notarize-app -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}"
  154. xcrun altool --notarize-app -f "${DEST_DMG}" --primary-bundle-id "${N_BUNDLE_ID}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1
  155. # Parse request uuid
  156. _requuid=$(cat "${_tmpout}" | grep "RequestUUID" | awk '{ print $3 }')
  157. echo "RequestUUID: ${_requuid}"
  158. if [ ! -z "${_requuid}" ]; then
  159. # Wait for Apple to confirm notarization is complete
  160. echo "Waiting for notarization to be complete.."
  161. for c in {20..0};do
  162. sleep 600
  163. xcrun altool --notarization-info "${_requuid}" --username "${N_USERNAME}" --password "${N_PASSWORD}" >${_tmpout} 2>&1
  164. _status=$(cat "${_tmpout}" | grep "Status:" | awk '{ print $2 }')
  165. if [ "${_status}" == "invalid" ]; then
  166. echo "Got invalid notarization!"
  167. break;
  168. fi
  169. if [ "${_status}" == "success" ]; then
  170. echo -n "Notarization successful! Stapling..."
  171. xcrun stapler staple -v "${DEST_DMG}"
  172. break;
  173. fi
  174. echo "Notarization in progress, waiting..."
  175. done
  176. else
  177. echo "Error getting RequestUUID, notarization unsuccessful"
  178. fi
  179. else
  180. echo "No notarization credentials supplied, skipping..."
  181. fi
  182. echo "..done. You should have ${DEST_DMG} ready to upload"