Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions scripts/sign-macos-broken.sh

This file was deleted.

39 changes: 39 additions & 0 deletions scripts/sign-macos-old.sh
Original file line number Diff line number Diff line change
@@ -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"
139 changes: 108 additions & 31 deletions scripts/sign-macos.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,116 @@
#!/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 ---
environment=(
"MACOS_CERTIFICATE"
"MACOS_CERTIFICATE_PWD"
"MACOS_CI_KEYCHAIN_PWD"
"MACOS_CERTIFICATE_NAME"
"MACOS_NOTARY_TEAM_ID"
"MACOS_NOTARY_KEY_ID"
"MACOS_NOTARY_KEY"
"MACOS_NOTARY_ISSUER_ID"
)

# 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."
# --- 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
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"

# --- Step 2: Decode and install the signing certificate ---
echo "Decoding certificate..."
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 "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

# --- 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"

# --- 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" \
--issuer "$MACOS_NOTARY_ISSUER_ID" \
--output-format json)

echo "$SUBMIT_JSON"
SUBMIT_ID=$(echo "$SUBMIT_JSON" | jq -r .id)

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" \
--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" \
notarization-log.json || true
cat notarization-log.json || true

if [[ $WAIT_STATUS -ne 0 ]]; then
echo "Notarization did not succeed (wait exit code: $WAIT_STATUS)"
exit $WAIT_STATUS
fi

# --- Step 9: Staple the notarization ticket ---
echo "Stapling notarization ticket..."
xcrun stapler staple "$APP_PATH"

# --- Step 10: Final Gatekeeper check (AFTER stapling) ---
echo "Running Gatekeeper assessment..."
spctl --assess --type execute --verbose "$APP_PATH"

echo "Done! App is signed, notarized, and stapled."
Loading