#!/bin/bash # Notarize the macOS release artefacts with Apple and staple the ticket where one can be stapled. # # tools/notarize_macos.sh ... # # The programs inside must already carry a Developer ID signature with hardened runtime and secure # timestamp: configure with -DJFJOCH_MACOS_SIGNING_IDENTITY= and let cpack produce # the artefact (see the top-level CMakeLists.txt). The same certificate signs the .dmg here: the # one JFJOCH_MACOS_SIGNING_IDENTITY names, else the Developer ID Application in the keychain. Needs # notarytool credentials stored once on the machine, under the profile named by JFJOCH_NOTARY_PROFILE # (default jfjoch-notary). On an unattended machine store them in the login keychain file: without # --keychain they go into the data-protection keychain, which is unreadable while the screen is # locked, and the step then fails with "No Keychain password item found". # # xcrun notarytool store-credentials jfjoch-notary --apple-id --team-id \ # --keychain ~/Library/Keychains/login.keychain-db # # .dmg signed with the same Developer ID, submitted, the ticket stapled to the image. # .tar.gz the rugnux binary inside is zipped and submitted; Apple then knows its hash, which is # all Gatekeeper needs (a bare executable has nowhere to staple a ticket). The archive is # shipped unchanged. set -euo pipefail profile=${JFJOCH_NOTARY_PROFILE:-jfjoch-notary} identity=${JFJOCH_MACOS_SIGNING_IDENTITY:-$(security find-identity -v -p codesigning | sed -n 's/^ *[0-9]*) \([0-9A-F]*\) "Developer ID Application: .*/\1/p' | head -1)} if [ -z "$identity" ]; then echo "no Developer ID Application identity in the keychain"; exit 1; fi submit() { # submit : wait for Apple's verdict, print the log on rejection local out id status out=$(xcrun notarytool submit "$1" --keychain-profile "$profile" --wait --output-format plist) id=$(echo "$out" | plutil -extract id raw -) status=$(echo "$out" | plutil -extract status raw -) echo "notarization of $(basename "$1"): $status (submission $id)" if [ "$status" != "Accepted" ]; then xcrun notarytool log "$id" --keychain-profile "$profile" exit 1 fi } for file in "$@"; do case "$file" in *.dmg) codesign --force --timestamp --sign "$identity" "$file" submit "$file" xcrun stapler staple "$file" spctl -a -t open --context context:primary-signature -v "$file" ;; *.tar.gz|*.tgz) tmp=$(mktemp -d) tar xf "$file" -C "$tmp" bin=$(find "$tmp" -name rugnux -type f) ditto -c -k "$bin" "$tmp/rugnux.zip" submit "$tmp/rugnux.zip" rm -rf "$tmp" ;; *) echo "don't know how to notarize $file"; exit 1 ;; esac done