Das folgende Skript notarisiert macOS Apps, Packages und DMG-Dateien voll automatisch. Dabei wird die original Datei notarisiert – eine extra ZIP-Datei muß vorher nicht erstellt werden.
Bitte beachten: Bevor wir die App notarisieren können, muss Sie erfolgreich code-signiert werden. Das Skript zum Code-Signieren von macOS Apps gibt es hier.
Das Gleiche gilt für PKG- und DMG-Dateien. Bei DMGs müssen alle darin enthaltenen Apps oder PKGs ebenfalls signiert werden.
Doch nun zum Notarization Script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
#!/bin/bash -u # # notarize 1.0.1 # # Notarize an macOS app bundles, DMGs and PKGs. # This script works with the original bundle, not with a extra ZIP file. # Submitting the bundle ID for a app bundle is optional. # Based on code by rednoah. # # Changelog: # 1.0.1: # - Added automatic bundle id extraction from app bundles. # 1.0.0: # - Simplified command line parameters. # - Added automatic ZIP file creation. # - Fixed UUID extraction. # - Stapler won't be called, if the package is invalid. # # CALL: # notarize appFilePackage [bundleID] # # E.g.: # ./notarize myapp.app # ./notarize myapp.pkg com.marketmix.mypkg # # (c)2020 Harald Schneider USR="h_schneider@marketmix.com" PWD="xxxx-xxxx-xxxx-xxxx-xxxx" if [ "$#" -eq 1 ]; then BUNDLE_ID=$(mdls -name kMDItemCFBundleIdentifier -r "$1") if [ $BUNDLE_ID == "(null)" ]; then echo echo "ERROR: Could not extract the Bundle ID." echo "Please submit a valid Bundle ID in a 2nd parameter!" exit fi echo echo "Extracted Bundle ID is ${BUNDLE_ID}" else BUNDLE_ID="$2" echo fi BUNDLE_APP="$1" BUNDLE_ZIP="${BUNDLE_ID}".zip # Create temporary files NOTARIZE_APP_LOG=$(mktemp -t notarize-app) NOTARIZE_INFO_LOG=$(mktemp -t notarize-info) # Delete temporary files on exit function finish { rm "$NOTARIZE_APP_LOG" "$NOTARIZE_INFO_LOG" "$BUNDLE_ZIP" } trap finish EXIT echo "Building ZIP Archive: ${BUNDLE_ZIP} ..." ditto -ck --sequesterRsrc --keepParent "${BUNDLE_APP}" "${BUNDLE_ZIP}" echo "Submitting notarization request. This can take a while ...." # Submit app for notarization if xcrun altool --notarize-app --primary-bundle-id "$BUNDLE_ID" --username "$USR" --password "$PWD" -f "$BUNDLE_ZIP" > "$NOTARIZE_APP_LOG" 2>&1; then echo --------------------------------------------------------- cat "$NOTARIZE_APP_LOG"|awk NF echo --------------------------------------------------------- RequestUUID=$(awk -F ' = ' '/RequestUUID/ {print $2}' "$NOTARIZE_APP_LOG") echo "Extracted UUID is" $RequestUUID echo --------------------------------------------------------- echo "Waiting for the Apple Notarization Server:" echo "The status will be updated every 60 seconds ..." # Check status periodically while sleep 60 && date; do echo --------------------------------------------------------- echo "Notarization in progress ...." # Check notarization status if xcrun altool --notarization-info "$RequestUUID" --username "$USR" --password "$PWD" > "$NOTARIZE_INFO_LOG" 2>&1; then RESPONSE=$(awk -F ': ' '/Status Message/ {print $2}' "$NOTARIZE_INFO_LOG") if [ "$RESPONSE" != "" ]; then echo --------------------------------------------------------- echo "The Apple Notarization Server said: ${RESPONSE}" fi # Check server response before starting Stapler if [ "$RESPONSE" == "Package Approved" ]; then echo --------------------------------------------------------- echo "Running stapler. This can take a while ...." # Once notarization is complete, run stapler and exit if ! grep -q "Status: in progress" "$NOTARIZE_INFO_LOG"; then xcrun stapler staple "$BUNDLE_APP" exit $? fi fi else echo --------------------------------------------------------- cat "$NOTARIZE_INFO_LOG" 1>&2 exit 1 fi done else echo --------------------------------------------------------- echo "Logged result:" cat "$NOTARIZE_APP_LOG" 1>&2 exit 1 fi |
In den Variablen USR und PWD werden die eigenen Daten hinterlegt. Bei PWD handelt es sich um das App Specific Password. Danach speichern wir das Script unter “notarize” und setzen das Executable Flag mit
1 |
chmod +x notarize |
Gestartet wird das Ganze dann mit
1 |
notarize MyAPP.app com.marketmix.myapp |
Im o.g. Beispiel ist MyApp.app der Name unseres App Bundles und com.marketmix.myapp der Bundle Identifier. Dieser muss natürlich mit dem tatsächlichen Bundle Identifier in der App übereinstimmen. Die Angabe des Bundle Identifiers ist bei App Bundles optional. Wird der Parameter weg gelassen, so extrahiert das Script die ID aus dem App Bundle.
Das Skript erstellt automatisch eine temporäre ZIP-Datei, sendet diese an den Apple Notarization Server und startet die Notarisierung. Danach prüft es alle 60 Sekunden den Fortschritt der Notarisierung. Wurde diese erfolgreich abgeschlossen, wird das erhaltene Ticket in die original Datei eingepflegt.
Wenn die Notarisierung geklappt, hat steht im Output
1 2 3 4 5 6 7 |
... --------------------------------------------------------- The Apple Notarization Server said: Package Approved --------------------------------------------------------- Running stapler. This can take a while .... Processing: MyApp.app The staple and validate action worked! |
oder eine entsprechende Fehlermeldung.