#!/bin/bash # Baut Onyx als notarisiertes DMG. # # Voraussetzungen — beide einmalig einzurichten: # # 1. Ein Zertifikat „Developer ID Application: … (PP34X97WS3)" im Schlüsselbund. # Xcode → Einstellungen → Konten → Manage Certificates → + → # Developer ID Application. Das Entwicklerzertifikat („Apple Development") # genügt NICHT: damit signierte Apps lassen sich nicht notarisieren und # laufen auf keinem fremden Mac. # # 2. Ein Zugangsprofil für notarytool: # xcrun notarytool store-credentials "Onyx" \ # --apple-id "" --team-id PP34X97WS3 \ # --password "" # Das app-spezifische Passwort kommt von appleid.apple.com, nicht das # normale Kennwort. # # Danach genügt: Scripts/release.sh set -euo pipefail export DEVELOPER_DIR=${DEVELOPER_DIR:-/Applications/Xcode.app/Contents/Developer} ROOT="$(cd "$(dirname "$0")/.." && pwd)" BUILD="$ROOT/build/release" PROFILE="${NOTARY_PROFILE:-Onyx}" TEAM="PP34X97WS3" APP_NAME="Onyx" cd "$ROOT" VERSION=$(awk -F'"' '/MARKETING_VERSION/ {print $2; exit}' project.yml) DMG="$BUILD/${APP_NAME}-${VERSION}.dmg" fail() { echo "✗ $*" >&2; exit 1; } step() { echo; echo "── $* ──"; } # ---------------------------------------------------------------- Vorprüfung # # Beide Prüfungen vorweg statt unterwegs: ein Fehlschlag nach dem Archivieren # kostet Minuten, und die Notarisierung scheitert sonst erst nach dem Hochladen. step "Vorprüfung" security find-identity -v -p codesigning | grep -q "Developer ID Application" \ || fail "Kein „Developer ID Application“-Zertifikat im Schlüsselbund. Siehe Kopf dieses Skripts." xcrun notarytool history --keychain-profile "$PROFILE" >/dev/null 2>&1 \ || fail "Kein notarytool-Profil „$PROFILE“. Siehe Kopf dieses Skripts." command -v xcodegen >/dev/null || fail "xcodegen fehlt (brew install xcodegen)" echo "✓ Zertifikat, Notarisierungsprofil und xcodegen vorhanden" step "Projekt erzeugen" xcodegen generate step "Tests" (cd Packages/OnyxKit && swift test 2>&1 | tail -3) # ------------------------------------------------------------------ Bauen # # Über ein Archiv und nicht über `build`: nur exportArchive signiert das # fertige Bundle vollständig mit der Verteilungsidentität, samt aller # eingebetteten Programme. step "Archivieren" rm -rf "$BUILD" mkdir -p "$BUILD" xcodebuild archive \ -project Onyx.xcodeproj -scheme Onyx -configuration Release \ -archivePath "$BUILD/$APP_NAME.xcarchive" \ -allowProvisioningUpdates \ CODE_SIGN_STYLE=Automatic \ CODE_SIGN_IDENTITY="Developer ID Application" \ DEVELOPMENT_TEAM="$TEAM" \ | grep -E "error:|warning: .*deprecated|ARCHIVE SUCCEEDED" || true [ -d "$BUILD/$APP_NAME.xcarchive" ] || fail "Archivieren fehlgeschlagen" cat > "$BUILD/export.plist" < methoddeveloper-id teamID$TEAM signingStyleautomatic destinationexport PLIST step "Exportieren" xcodebuild -exportArchive \ -archivePath "$BUILD/$APP_NAME.xcarchive" \ -exportPath "$BUILD/export" \ -exportOptionsPlist "$BUILD/export.plist" \ -allowProvisioningUpdates | tail -3 APP="$BUILD/export/$APP_NAME.app" [ -d "$APP" ] || fail "Export fehlgeschlagen" # --------------------------------------------------------------- Nachprüfen # # Was hier durchrutscht, lehnt Apple nach dem Hochladen ab. Die drei Punkte # sind genau die, an denen dieses Projekt eine Sonderbehandlung hat. step "Signatur prüfen" codesign --verify --deep --strict --verbose=2 "$APP" 2>&1 | tail -3 codesign -d --entitlements - "$APP" 2>/dev/null | grep -q "application-groups" \ || fail "App-Group fehlt in den Entitlements — Calendarr wäre unerreichbar" # Der Helfer trägt seine Kennung in der Binary, nicht in einer Info.plist. # Stimmt sie nicht, lehnt die App ihren eigenen Helfer ab. HELPER_ID=$(codesign -d --verbose=2 "$APP/Contents/MacOS/OnyxHelper" 2>&1 \ | awk -F= '/^Identifier=/ {print $2}') [ "$HELPER_ID" = "com.scarriffleservices.onyx.helper" ] \ || fail "Helfer trägt die Kennung „$HELPER_ID“ statt com.scarriffleservices.onyx.helper" # Ad-hoc signierte Bibliotheken sind der häufigste Ablehnungsgrund. if codesign -dv "$APP/Contents/Resources/Vendor/MediaRemoteAdapter.framework" 2>&1 \ | grep -q "adhoc"; then fail "MediaRemoteAdapter.framework ist ad-hoc signiert — die Notarisierung lehnt das ab" fi echo "✓ Signaturen, Entitlements, Helfer-Kennung und Adapter in Ordnung" # ------------------------------------------------------------------- DMG step "DMG bauen" STAGE="$BUILD/stage" rm -rf "$STAGE"; mkdir -p "$STAGE" cp -R "$APP" "$STAGE/" ln -s /Applications "$STAGE/Applications" rm -f "$DMG" hdiutil create -volname "$APP_NAME" -srcfolder "$STAGE" -ov -format UDZO "$DMG" | tail -1 # Das DMG selbst wird mitsigniert — sonst meldet Gatekeeper beim Öffnen einen # unbekannten Entwickler, obwohl die App darin einwandfrei ist. codesign --force --sign "Developer ID Application" --timestamp "$DMG" # ---------------------------------------------------------- Notarisierung step "Notarisieren (das dauert)" xcrun notarytool submit "$DMG" --keychain-profile "$PROFILE" --wait \ || fail "Notarisierung abgelehnt. Ursache: xcrun notarytool log --keychain-profile $PROFILE" step "Ticket anheften" # Ohne Stapeln braucht der erste Start des Nutzers eine Netzverbindung. xcrun stapler staple "$DMG" xcrun stapler validate "$DMG" step "Abschließende Prüfung" spctl -a -t open --context context:primary-signature -v "$DMG" 2>&1 | tail -2 echo echo "✓ Fertig: $DMG"