From 9b77e1aca9d2f0a5163c5794c2c7c34e2bffd8b7 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Wed, 22 Apr 2026 22:52:31 +0800 Subject: [PATCH 1/2] attempt fix from orvar --- scripts/sign-macos-broken.sh | 68 -------------------- scripts/sign-macos-old.sh | 39 ++++++++++++ scripts/sign-macos.sh | 118 ++++++++++++++++++++++++++--------- 3 files changed, 126 insertions(+), 99 deletions(-) delete mode 100755 scripts/sign-macos-broken.sh create mode 100755 scripts/sign-macos-old.sh diff --git a/scripts/sign-macos-broken.sh b/scripts/sign-macos-broken.sh deleted file mode 100755 index eeafe4f..0000000 --- a/scripts/sign-macos-broken.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -set -euo pipefail - -RELEASE_DIR="target/release" -APP_DIR="$RELEASE_DIR/macos" -APP_NAME="Rustcast.app" -APP_PATH="$APP_DIR/$APP_NAME" - -# --- Required env vars (using the names you provided) --- -environment=( - "MACOS_CERTIFICATE" - "MACOS_CERTIFICATE_PWD" - "MACOS_CI_KEYCHAIN_PWD" - "MACOS_CERTIFICATE_NAME" - "MACOS_NOTARIZATION_PWD" - "MACOS_NOTARY_TEAM_ID" - "MACOS_NOTARY_KEY_ID" - "MACOS_NOTARY_KEY" -) - -for var in "${environment[@]}"; do - if [[ -z "${!var:-}" ]]; then - echo "Error: $var is not set" - exit 1 - fi -done - -# Optional: only needed if you still want to keep this around -: "${MACOS_NOTARISATION_APPLE_ID:=}" - -echo "Decoding certificate" -echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 - -echo "Installing cert in a new keychain" -security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain -security default-keychain -s build.keychain -security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain -security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign -security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain - -echo "Signing..." -/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime --timestamp "$APP_PATH" -v - -echo "Creating temp notarization archive" -ditto -c -k --keepParent "$APP_PATH" "notarization.zip" - -echo "Notarize app (API key auth)" -# MACOS_NOTARY_KEY can be either: -# - the *contents* of the .p8 key, or -# - base64 of the .p8 key (recommended for CI) -# -# If it's base64, decode it first. -NOTARY_KEY_FILE="AuthKey.p8" -if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then - printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" -else - printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" -fi - -# xcrun notarytool submit "notarization.zip" \ -# --team-id "$MACOS_NOTARY_TEAM_ID" \ -# --issuer "$MACOS_NOTARY_ISSUER_ID" \ -# --key-id "$MACOS_NOTARY_KEY_ID" \ -# --key "$NOTARY_KEY_FILE" \ -# --wait - -echo "Attach staple" -xcrun stapler staple "$APP_PATH" diff --git a/scripts/sign-macos-old.sh b/scripts/sign-macos-old.sh new file mode 100755 index 0000000..3b1c162 --- /dev/null +++ b/scripts/sign-macos-old.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env -S bash -e + +ENTITLEMENTS_PATH="assets/entitlements.plist" + +APP_BUNDLE_PATH="${APP_BUNDLE_PATH:?APP_BUNDLE_PATH not set}" + +# 1. Create a temporary keychain and import certificate +KEYCHAIN=build.keychain-db + +if security list-keychains | grep -q "$KEYCHAIN"; then + echo "Keychain $KEYCHAIN already exists, using existing keychain." +else + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +fi + +security default-keychain -s "$KEYCHAIN" +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +security set-keychain-settings "$KEYCHAIN" +security default-keychain -s "$KEYCHAIN" +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +security set-keychain-settings "$KEYCHAIN" + +echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 +security import certificate.p12 \ + -k "$KEYCHAIN" \ + -P "$MACOS_CERTIFICATE_PWD" \ + -T /usr/bin/codesign + +security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" + +# 2. Sign app bundle +codesign --deep --force --options runtime --timestamp \ + --entitlements $ENTITLEMENTS_PATH \ + --sign "$MACOS_CERTIFICATE_NAME" \ + "$APP_BUNDLE_PATH" + +codesign --verify --deep --strict --verbose=2 "$APP_BUNDLE_PATH" +echo "Signed app at $APP_BUNDLE_PATH" diff --git a/scripts/sign-macos.sh b/scripts/sign-macos.sh index 3b1c162..0cd5d81 100755 --- a/scripts/sign-macos.sh +++ b/scripts/sign-macos.sh @@ -1,39 +1,95 @@ -#!/usr/bin/env -S bash -e +#!/bin/bash +set -euo pipefail -ENTITLEMENTS_PATH="assets/entitlements.plist" +RELEASE_DIR="target/release" +APP_DIR="$RELEASE_DIR/macos" +APP_NAME="Rustcast.app" +APP_PATH="$APP_DIR/$APP_NAME" -APP_BUNDLE_PATH="${APP_BUNDLE_PATH:?APP_BUNDLE_PATH not set}" +# --- Required env vars (using the names you provided) --- +environment=( + "MACOS_CERTIFICATE" + "MACOS_CERTIFICATE_PWD" + "MACOS_CI_KEYCHAIN_PWD" + "MACOS_CERTIFICATE_NAME" + "MACOS_NOTARIZATION_PWD" + "MACOS_NOTARY_TEAM_ID" + "MACOS_NOTARY_KEY_ID" + "MACOS_NOTARY_KEY" +) -# 1. Create a temporary keychain and import certificate -KEYCHAIN=build.keychain-db +for var in "${environment[@]}"; do + if [[ -z "${!var:-}" ]]; then + echo "Error: $var is not set" + exit 1 + fi +done -if security list-keychains | grep -q "$KEYCHAIN"; then - echo "Keychain $KEYCHAIN already exists, using existing keychain." +# Optional: only needed if you still want to keep this around +: "${MACOS_NOTARISATION_APPLE_ID:=}" + +echo "Decoding certificate" +echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 + +echo "Installing cert in a new keychain" +security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain +security default-keychain -s build.keychain +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain +security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign +security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + +echo "Signing..." +/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime --timestamp "$APP_PATH" -v + +/usr/bin/codesign --verify --deep --strict --verbose=2 "$APP_PATH" +spctl --assess --type execute --verbose "$APP_PATH" + +echo "Creating temp notarization archive" +ditto -c -k --keepParent "$APP_PATH" "notarization.zip" + +SUBMIT_JSON=$(xcrun notarytool submit "notarization.zip" \ + --key "$NOTARY_KEY_FILE" \ + --key-id "$MACOS_NOTARY_KEY_ID" \ + --issuer "$MACOS_NOTARY_ISSUER_ID" \ + --output-format json) + +echo "$SUBMIT_JSON" + +SUBMIT_ID=$(echo "$SUBMIT_JSON" | jq -r .id) + +WAIT_STATUS=0 + +xcrun notarytool wait "$SUBMIT_ID" \ + --key "$NOTARY_KEY_FILE" --key-id "$MACOS_NOTARY_KEY_ID" --issuer "$MACOS_NOTARY_ISSUER_ID" \ + --timeout 30m || WAIT_STATUS=$? +xcrun notarytool log "$SUBMIT_ID" \ + --key "$NOTARY_KEY_FILE" --key-id "$MACOS_NOTARY_KEY_ID" --issuer "$MACOS_NOTARY_ISSUER_ID" \ + notarization-log.json || true +cat notarization-log.json || true +if [[ $WAIT_STATUS -ne 0 ]]; then + echo "Notarization did not succeed (wait exit $WAIT_STATUS)" + exit $WAIT_STATUS +fi + +echo "Notarize app (API key auth)" +# MACOS_NOTARY_KEY can be either: +# - the *contents* of the .p8 key, or +# - base64 of the .p8 key (recommended for CI) +# +# If it's base64, decode it first. +NOTARY_KEY_FILE="AuthKey.p8" +if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then + printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" else - security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" + printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" fi -security default-keychain -s "$KEYCHAIN" -security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" -security set-keychain-settings "$KEYCHAIN" -security default-keychain -s "$KEYCHAIN" -security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" -security set-keychain-settings "$KEYCHAIN" +# xcrun notarytool submit "notarization.zip" \ +# --team-id "$MACOS_NOTARY_TEAM_ID" \ +# --issuer "$MACOS_NOTARY_ISSUER_ID" \ +# --key-id "$MACOS_NOTARY_KEY_ID" \ +# --key "$NOTARY_KEY_FILE" \ +# --wait -echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 -security import certificate.p12 \ - -k "$KEYCHAIN" \ - -P "$MACOS_CERTIFICATE_PWD" \ - -T /usr/bin/codesign - -security set-key-partition-list -S apple-tool:,apple:,codesign: \ - -s -k "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" - -# 2. Sign app bundle -codesign --deep --force --options runtime --timestamp \ - --entitlements $ENTITLEMENTS_PATH \ - --sign "$MACOS_CERTIFICATE_NAME" \ - "$APP_BUNDLE_PATH" - -codesign --verify --deep --strict --verbose=2 "$APP_BUNDLE_PATH" -echo "Signed app at $APP_BUNDLE_PATH" +echo "Attach staple" +xcrun stapler staple "$APP_PATH" From 4b8a6dbf0efdb773d45649bbdab99364529d8c6d Mon Sep 17 00:00:00 2001 From: unsecretised Date: Wed, 22 Apr 2026 23:06:11 +0800 Subject: [PATCH 2/2] turns out order was wrong --- scripts/sign-macos.sh | 93 ++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/scripts/sign-macos.sh b/scripts/sign-macos.sh index 0cd5d81..774d755 100755 --- a/scripts/sign-macos.sh +++ b/scripts/sign-macos.sh @@ -6,16 +6,16 @@ APP_DIR="$RELEASE_DIR/macos" APP_NAME="Rustcast.app" APP_PATH="$APP_DIR/$APP_NAME" -# --- Required env vars (using the names you provided) --- +# --- Required env vars --- environment=( "MACOS_CERTIFICATE" "MACOS_CERTIFICATE_PWD" "MACOS_CI_KEYCHAIN_PWD" "MACOS_CERTIFICATE_NAME" - "MACOS_NOTARIZATION_PWD" "MACOS_NOTARY_TEAM_ID" "MACOS_NOTARY_KEY_ID" "MACOS_NOTARY_KEY" + "MACOS_NOTARY_ISSUER_ID" ) for var in "${environment[@]}"; do @@ -25,28 +25,47 @@ for var in "${environment[@]}"; do fi done -# Optional: only needed if you still want to keep this around -: "${MACOS_NOTARISATION_APPLE_ID:=}" +# --- Step 1: Decode the notarization API key FIRST --- +echo "Preparing notarization API key..." +NOTARY_KEY_FILE="AuthKey.p8" +if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then + printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" +else + printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" +fi -echo "Decoding certificate" +# --- Step 2: Decode and install the signing certificate --- +echo "Decoding certificate..." echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 -echo "Installing cert in a new keychain" +echo "Installing cert in a new keychain..." security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain security default-keychain -s build.keychain security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain -echo "Signing..." -/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime --timestamp "$APP_PATH" -v - +# --- Step 3: Sign the app --- +echo "Signing app..." +/usr/bin/codesign \ + --force \ + --deep \ + --options runtime \ + --timestamp \ + -s "$MACOS_CERTIFICATE_NAME" \ + -v \ + "$APP_PATH" + +# --- Step 4: Verify the signature (not notarization yet) --- +echo "Verifying signature..." /usr/bin/codesign --verify --deep --strict --verbose=2 "$APP_PATH" -spctl --assess --type execute --verbose "$APP_PATH" -echo "Creating temp notarization archive" +# --- Step 5: Create notarization zip --- +echo "Creating notarization archive..." ditto -c -k --keepParent "$APP_PATH" "notarization.zip" +# --- Step 6: Submit for notarization --- +echo "Submitting for notarization..." SUBMIT_JSON=$(xcrun notarytool submit "notarization.zip" \ --key "$NOTARY_KEY_FILE" \ --key-id "$MACOS_NOTARY_KEY_ID" \ @@ -54,42 +73,44 @@ SUBMIT_JSON=$(xcrun notarytool submit "notarization.zip" \ --output-format json) echo "$SUBMIT_JSON" - SUBMIT_ID=$(echo "$SUBMIT_JSON" | jq -r .id) -WAIT_STATUS=0 +if [[ -z "$SUBMIT_ID" || "$SUBMIT_ID" == "null" ]]; then + echo "Error: Failed to get submission ID from notarytool" + exit 1 +fi + +echo "Submission ID: $SUBMIT_ID" +# --- Step 7: Wait for notarization to complete --- +echo "Waiting for notarization result..." +WAIT_STATUS=0 xcrun notarytool wait "$SUBMIT_ID" \ - --key "$NOTARY_KEY_FILE" --key-id "$MACOS_NOTARY_KEY_ID" --issuer "$MACOS_NOTARY_ISSUER_ID" \ + --key "$NOTARY_KEY_FILE" \ + --key-id "$MACOS_NOTARY_KEY_ID" \ + --issuer "$MACOS_NOTARY_ISSUER_ID" \ --timeout 30m || WAIT_STATUS=$? + +# --- Step 8: Fetch and print the notarization log --- +echo "Fetching notarization log..." xcrun notarytool log "$SUBMIT_ID" \ - --key "$NOTARY_KEY_FILE" --key-id "$MACOS_NOTARY_KEY_ID" --issuer "$MACOS_NOTARY_ISSUER_ID" \ + --key "$NOTARY_KEY_FILE" \ + --key-id "$MACOS_NOTARY_KEY_ID" \ + --issuer "$MACOS_NOTARY_ISSUER_ID" \ notarization-log.json || true cat notarization-log.json || true + if [[ $WAIT_STATUS -ne 0 ]]; then - echo "Notarization did not succeed (wait exit $WAIT_STATUS)" + echo "Notarization did not succeed (wait exit code: $WAIT_STATUS)" exit $WAIT_STATUS fi -echo "Notarize app (API key auth)" -# MACOS_NOTARY_KEY can be either: -# - the *contents* of the .p8 key, or -# - base64 of the .p8 key (recommended for CI) -# -# If it's base64, decode it first. -NOTARY_KEY_FILE="AuthKey.p8" -if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then - printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" -else - printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" -fi +# --- Step 9: Staple the notarization ticket --- +echo "Stapling notarization ticket..." +xcrun stapler staple "$APP_PATH" -# xcrun notarytool submit "notarization.zip" \ -# --team-id "$MACOS_NOTARY_TEAM_ID" \ -# --issuer "$MACOS_NOTARY_ISSUER_ID" \ -# --key-id "$MACOS_NOTARY_KEY_ID" \ -# --key "$NOTARY_KEY_FILE" \ -# --wait +# --- Step 10: Final Gatekeeper check (AFTER stapling) --- +echo "Running Gatekeeper assessment..." +spctl --assess --type execute --verbose "$APP_PATH" -echo "Attach staple" -xcrun stapler staple "$APP_PATH" +echo "Done! App is signed, notarized, and stapled."