sign-notarize.bash 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/env bash
  2. set -e
  3. readonly usage='usage: sign-notarize.bash -i <id> -k <keychain-profile> [--] <package>.dmg
  4. Sign and notarize the "CMake.app" bundle inside the given "<package>.dmg" disk image.
  5. Also produce a "<package>.tar.gz" tarball containing the same "CMake.app".
  6. Options:
  7. -i <id> Signing Identity
  8. -k <keychain-profile> Keychain profile containing stored credentials
  9. Create the keychain profile ahead of time using
  10. xcrun notarytool store-credentials <keychain-profile> \
  11. --apple-id <dev-acct> --team-id <team-id> [--password <app-specific-password>]
  12. where:
  13. <dev-acct> is an Apple ID of a developer account
  14. <team-id> is from https://developer.apple.com/account/#!/membership
  15. <app-specific-password> is generated via https://support.apple.com/en-us/HT204397
  16. If --password is omitted, notarytool will prompt for it.
  17. This creates a keychain item called "com.apple.gke.notary.tool" with an
  18. account name "com.apple.gke.notary.tool.saved-creds.<keychain-profile>".
  19. '
  20. cleanup() {
  21. if test -d "$tmpdir"; then
  22. rm -rf "$tmpdir"
  23. fi
  24. if test -d "$vol_path"; then
  25. hdiutil detach "$vol_path"
  26. fi
  27. }
  28. trap "cleanup" EXIT
  29. die() {
  30. echo "$@" 1>&2; exit 1
  31. }
  32. id=''
  33. keychain_profile=''
  34. while test "$#" != 0; do
  35. case "$1" in
  36. -i) shift; id="$1" ;;
  37. -k) shift; keychain_profile="$1" ;;
  38. --) shift ; break ;;
  39. -*) die "$usage" ;;
  40. *) break ;;
  41. esac
  42. shift
  43. done
  44. case "$1" in
  45. *.dmg) readonly dmg="$1"; shift ;;
  46. *) die "$usage" ;;
  47. esac
  48. test "$#" = 0 || die "$usage"
  49. # Verify arguments.
  50. if test -z "$id" -o -z "$keychain_profile"; then
  51. die "$usage"
  52. fi
  53. # Verify environment.
  54. if ! xcrun --find notarytool 2>/dev/null; then
  55. die "'xcrun notarytool' not found"
  56. fi
  57. readonly tmpdir="$(mktemp -d)"
  58. # Prepare entitlements.
  59. readonly entitlements_xml="$tmpdir/entitlements.xml"
  60. echo '<?xml version="1.0" encoding="UTF-8"?>
  61. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  62. <plist version="1.0">
  63. <dict>
  64. <key>com.apple.security.cs.allow-dyld-environment-variables</key>
  65. <true/>
  66. </dict>
  67. </plist>' > "$entitlements_xml"
  68. # Convert from read-only original image to read-write.
  69. readonly udrw_dmg="$tmpdir/udrw.dmg"
  70. hdiutil convert "$dmg" -format UDRW -o "${udrw_dmg}"
  71. # Mount the temporary udrw image.
  72. readonly vol_name="$(basename "${dmg%.dmg}")"
  73. readonly vol_path="/Volumes/$vol_name"
  74. hdiutil attach "${udrw_dmg}"
  75. codesign --verify --timestamp --options=runtime --verbose --deep \
  76. -s "$id" \
  77. --entitlements "$entitlements_xml" \
  78. "$vol_path/CMake.app/Contents/bin/cmake" \
  79. "$vol_path/CMake.app/Contents/bin/ccmake" \
  80. "$vol_path/CMake.app/Contents/bin/ctest" \
  81. "$vol_path/CMake.app/Contents/bin/cpack" \
  82. "$vol_path/CMake.app"
  83. ditto -c -k --keepParent "$vol_path/CMake.app" "$tmpdir/CMake.app.zip"
  84. xcrun notarytool submit "$tmpdir/CMake.app.zip" --keychain-profile "$keychain_profile" --wait
  85. xcrun stapler staple "$vol_path/CMake.app"
  86. # Create a tarball of the volume next to the original disk image.
  87. readonly tar_gz="${dmg/%.dmg/.tar.gz}"
  88. tar cvzf "$tar_gz" -C /Volumes "$vol_name/CMake.app"
  89. # Unmount the modified udrw image.
  90. hdiutil detach "$vol_path"
  91. # Convert back to read-only, compressed image.
  92. hdiutil convert "${udrw_dmg}" -format UDZO -imagekey zlib-level=9 -ov -o "$dmg"