#!/bin/bash # # notarize.sh # Zyquo Atlas # # Author: Simon-Pierre Boucher # Mail: contact@spboucher.ai # # Developer ID signing + notarization + stapling for an assembled # Zyquo Atlas.app (Phase 8). Identity, Team ID, and the notarytool keychain # profile are reused from the Zyquo family pipeline (zyquo-term). # # Usage: notarize.sh # Signs inside-out (nested resource bundles, then the app) with the Hardened # Runtime, zips with ditto, submits with notarytool --wait, staples, and # verifies spctl == "Notarized Developer ID". Secrets are never printed. # set -euo pipefail cd "$(dirname "$0")/.." APP_DIR="$1" IDENTITY="$2" KEYCHAIN_PROFILE="$3" ENTITLEMENTS="$4" ZIP_PATH="${APP_DIR%.app}.zip" [ -d "$APP_DIR" ] || { echo "ERROR: $APP_DIR missing — run 'make release' (assembles the bundle first)" >&2; exit 1; } echo "=== Signing (Developer ID, Hardened Runtime) ===" # Sign nested code first (SPM resource bundles carrying the Content/*.js and # icon), inside-out, so the outer signature stays valid. find "$APP_DIR/Contents" -name "*.bundle" -maxdepth 3 -print0 2>/dev/null \ | while IFS= read -r -d '' bundle; do echo " nested: $(basename "$bundle")" codesign --force --options runtime --timestamp \ --entitlements "$ENTITLEMENTS" --sign "$IDENTITY" "$bundle" done # Sign the app bundle (also signs Contents/MacOS/ZyquoAtlas). codesign --force --options runtime --timestamp \ --entitlements "$ENTITLEMENTS" --sign "$IDENTITY" "$APP_DIR" codesign --verify --deep --strict --verbose=2 "$APP_DIR" echo "Signature valid." echo "=== Packaging for notarization (ditto) ===" rm -f "$ZIP_PATH" ditto -c -k --keepParent "$APP_DIR" "$ZIP_PATH" echo "=== Submitting to notarytool (profile: $KEYCHAIN_PROFILE) ===" xcrun notarytool submit "$ZIP_PATH" --keychain-profile "$KEYCHAIN_PROFILE" --wait echo "=== Stapling ===" xcrun stapler staple "$APP_DIR" xcrun stapler validate "$APP_DIR" echo "=== Gatekeeper assessment ===" spctl -a -vvv --type execute "$APP_DIR" echo "Done: $APP_DIR is Developer ID–signed, notarized, and stapled."