Files
horizon-airdef/packaging/macos/notarize.sh
T
Ludovic Marie 3ffbb1cb9f Sign and notarize the macOS builds with Developer ID
With the repository variable MACOS_SIGN_IDENTITY set, the launcher's Horizon.app and .dmg and the
game's three programs are signed with the hardened runtime and a timestamp, notarized and (app,
dmg) stapled, from a keychain of the Mac mini's own that keychain.sh unlocks with its password from
1Password. Unset, everything is signed ad hoc as before. The launcher checks an updated bundle's
signature before and after swapping it in, and puts the old one back when it doesn't hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:20:34 +02:00

38 lines
1.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Notarizes signed macOS builds with Apple's notary service and staples the ticket to what can
# hold one: an .app (sent as a zip) and a .dmg are stapled, a .zip of bare programs can't be
# (Gatekeeper asks Apple online the first time one runs).
#
# packaging/macos/notarize.sh FILE...
#
# Uses the notarytool profile $MACOS_NOTARY_PROFILE in the keychain $MACOS_SIGN_KEYCHAIN, which
# `packaging/macos/keychain.sh unlock` unlocks and exports.
set -euo pipefail
profile=${MACOS_NOTARY_PROFILE:?the notarytool profile (packaging/macos/keychain.sh unlock)}
keychain=()
[[ -n "${MACOS_SIGN_KEYCHAIN:-}" ]] && keychain=(--keychain "$MACOS_SIGN_KEYCHAIN")
for file in "$@"; do
file=${file%/}
sent=$file
if [[ "$file" == *.app ]]; then
sent=$(mktemp -d)/$(basename "$file").zip
ditto -c -k --norsrc --noextattr --noqtn --keepParent "$file" "$sent"
fi
echo "Notarizing $(basename "$file")…"
result=$(xcrun notarytool submit "$sent" --keychain-profile "$profile" ${keychain[@]+"${keychain[@]}"} \
--wait --timeout 30m --output-format json)
[[ "$sent" == "$file" ]] || rm -rf "$(dirname "$sent")"
id=$(plutil -extract id raw -o - - <<< "$result")
status=$(plutil -extract status raw -o - - <<< "$result")
echo "$(basename "$file"): $status (submission $id)"
if [[ "$status" != Accepted ]]; then
xcrun notarytool log "$id" --keychain-profile "$profile" ${keychain[@]+"${keychain[@]}"} || true
echo "::error::$(basename "$file") was not notarized: $status"
exit 1
fi
case "$file" in
*.app | *.dmg) xcrun stapler staple "$file" && xcrun stapler validate "$file" ;;
esac
done