fix(actions): enhance macOS notarization workflow by simplifying action structure, removing unnecessary debug logging steps, and implementing custom DMG creation with installer script
All checks were successful
Test macOS Build Action / test-macos-build (push) Successful in 49m52s

This commit is contained in:
Ozgur 2025-04-16 21:45:15 +02:00
parent 4b7123d9e1
commit f1c3e9da5a
No known key found for this signature in database
GPG Key ID: 66CDF27505A35546
4 changed files with 38 additions and 749 deletions

View File

@ -1,6 +1,6 @@
name: "macOS Sign and Notarize"
description: "Signs and notarizes macOS applications with Developer ID certificate"
author: moersoy"
author: moersoy
inputs:
app-path:
@ -822,4 +822,3 @@ runs:
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
rm -f *-notarize.zip || true
echo "✅ Cleanup complete"

View File

@ -15,13 +15,6 @@ jobs:
lfs: true
fetch-depth: 0
# Enable debug logging
- name: Enable Debug Logging
run: |
echo "ACTIONS_RUNNER_DEBUG=true" >> $GITHUB_ENV
echo "ACTIONS_STEP_DEBUG=true" >> $GITHUB_ENV
shell: bash
# Setup environment for build
- name: Setup environment
run: |
@ -152,588 +145,50 @@ jobs:
fi
shell: bash
# Create a debug log file for notarize action
- name: Create debug log directory
run: |
mkdir -p debug_logs
echo "DEBUG_LOG_PATH=$(pwd)/debug_logs/notarize_log.txt" >> $GITHUB_ENV
shell: bash
# Beginning of macos-notarize steps
- name: Setup debug environment
id: setup-debug-env
run: |
# Create debug directory if env variable is set
if [[ -n "$DEBUG_LOG_PATH" ]]; then
mkdir -p "$(dirname "$DEBUG_LOG_PATH")"
touch "$DEBUG_LOG_PATH"
echo "Debug logging enabled to: $DEBUG_LOG_PATH" | tee -a "$DEBUG_LOG_PATH"
fi
# Define debug log helper function
echo '
# Helper function for debug logging
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
' > /tmp/debug_helpers.sh
chmod +x /tmp/debug_helpers.sh
# Log debug message directly
echo "DEBUG: Starting macOS notarize action"
echo "$(date "+%Y-%m-%d %H:%M:%S") - Starting macOS notarize action" >> "$DEBUG_LOG_PATH"
echo "DEBUG: App path: ${{ env.APP_PATH }}"
echo "$(date "+%Y-%m-%d %H:%M:%S") - App path: ${{ env.APP_PATH }}" >> "$DEBUG_LOG_PATH"
echo "DEBUG: Team ID: ${{ secrets.APPLE_TEAM_ID }}"
echo "$(date "+%Y-%m-%d %H:%M:%S") - Team ID: ${{ secrets.APPLE_TEAM_ID }}" >> "$DEBUG_LOG_PATH"
echo "DEBUG: Notarization method: api-key"
echo "$(date "+%Y-%m-%d %H:%M:%S") - Notarization method: api-key" >> "$DEBUG_LOG_PATH"
echo "DEBUG: Bundle ID: ${{ env.BUNDLE_ID }}"
echo "$(date "+%Y-%m-%d %H:%M:%S") - Bundle ID: ${{ env.BUNDLE_ID }}" >> "$DEBUG_LOG_PATH"
shell: bash
- name: Set up variables
id: setup
run: |
# Debug log helper
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
# Debugging info
debug_log "Setting up variables"
# Generate unique name for keychain
KEYCHAIN_NAME="build-keychain-$(uuidgen)"
KEYCHAIN_PASSWORD="$(uuidgen)"
echo "KEYCHAIN_NAME=$KEYCHAIN_NAME" >> $GITHUB_ENV
echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> $GITHUB_ENV
# Set paths
echo "APP_PATH=${{ env.APP_PATH }}" >> $GITHUB_ENV
# Generate working directory for temp files
WORK_DIR="$(mktemp -d)"
echo "WORK_DIR=$WORK_DIR" >> $GITHUB_ENV
# Set bundle id (from input or extract from app)
if [[ -n "${{ env.BUNDLE_ID }}" ]]; then
BUNDLE_ID="${{ env.BUNDLE_ID }}"
else
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "${{ env.APP_PATH }}/Contents/Info.plist")
fi
echo "BUNDLE_ID=$BUNDLE_ID" >> $GITHUB_ENV
# Get app name from bundle path
APP_NAME=$(basename "${{ env.APP_PATH }}" .app)
echo "APP_NAME=$APP_NAME" >> $GITHUB_ENV
# Set output directory
OUTPUT_DIR="$(pwd)/PackagedReleases"
mkdir -p "$OUTPUT_DIR"
echo "OUTPUT_DIR=$OUTPUT_DIR" >> $GITHUB_ENV
# Set package paths
ZIP_PATH="$OUTPUT_DIR/${APP_NAME}.zip"
DMG_PATH="$OUTPUT_DIR/${APP_NAME}.dmg"
echo "ZIP_PATH=$ZIP_PATH" >> $GITHUB_ENV
echo "DMG_PATH=$DMG_PATH" >> $GITHUB_ENV
# Set notarization variables based on method
debug_log "Using API key method for notarization"
# Create API key file - properly decode from base64
API_KEY_FILE="$WORK_DIR/api_key.p8"
debug_log "Creating API key file at: $API_KEY_FILE"
# Check if NOTARY_API_KEY_PATH is provided
if [[ -z "${{ secrets.NOTARY_API_KEY_PATH }}" ]]; then
debug_log "ERROR: NOTARY_API_KEY_PATH secret is empty"
exit 1
fi
# First try using the secret directly (assuming it's a PEM key directly)
echo "${{ secrets.NOTARY_API_KEY_PATH }}" > "$API_KEY_FILE"
# Check if it's already in PEM format
if grep -q "BEGIN PRIVATE KEY" "$API_KEY_FILE"; then
debug_log "Secret is already in PEM format, using directly"
else
debug_log "Secret is not in PEM format, trying to decode as base64"
# Try base64 decoding
echo "${{ secrets.NOTARY_API_KEY_PATH }}" | base64 -D > "$API_KEY_FILE.decoded" 2>/dev/null || true
# Check if decoded content is PEM
if [[ -s "$API_KEY_FILE.decoded" ]] && grep -q "BEGIN PRIVATE KEY" "$API_KEY_FILE.decoded"; then
debug_log "Successfully decoded secret from base64 to PEM"
mv "$API_KEY_FILE.decoded" "$API_KEY_FILE"
else
debug_log "ERROR: Secret is neither PEM nor valid base64-encoded PEM"
debug_log "Secret starts with: $(head -c 20 "$API_KEY_FILE" | xxd -p)"
if [[ -f "$API_KEY_FILE.decoded" ]]; then
debug_log "Decoded content starts with: $(head -c 20 "$API_KEY_FILE.decoded" | xxd -p)"
fi
exit 1
fi
fi
# Verify API key file exists and has content
if [[ ! -f "$API_KEY_FILE" ]]; then
debug_log "ERROR: API key file could not be created"
exit 1
fi
if [[ ! -s "$API_KEY_FILE" ]]; then
debug_log "ERROR: API key file is empty"
exit 1
fi
# Get file permissions and size for debugging
FILE_PERMS=$(ls -la "$API_KEY_FILE")
FILE_SIZE=$(wc -c < "$API_KEY_FILE")
debug_log "API key file ($FILE_SIZE bytes): $FILE_PERMS"
# Set proper permissions
chmod 600 "$API_KEY_FILE"
echo "API_KEY_FILE=$API_KEY_FILE" >> $GITHUB_ENV
debug_log "API key file created at: $API_KEY_FILE"
debug_log "API key ID: ${{ secrets.NOTARY_API_KEY_ID }}"
debug_log "API key issuer ID: ${{ secrets.NOTARY_API_KEY_ISSUER_ID }}"
shell: bash
- name: Setup keychain
id: setup-keychain
run: |
# Debug log helper
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
debug_log "Setting up keychain"
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
security default-keychain -s "$KEYCHAIN_NAME"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
security set-keychain-settings -t 3600 -u "$KEYCHAIN_NAME"
# Create certificate file
CERTIFICATE_PATH="$WORK_DIR/certificate.p12"
echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 --decode > "$CERTIFICATE_PATH"
# Add to keychain
debug_log "Importing certificate into keychain"
security import "$CERTIFICATE_PATH" -k "$KEYCHAIN_NAME" -P "${{ secrets.MACOS_CERTIFICATE_PWD }}" -T /usr/bin/codesign
# Add to search list and set as default
security list-keychains -d user -s "$KEYCHAIN_NAME" login.keychain
security default-keychain -s "$KEYCHAIN_NAME"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
# Allow codesign to access keychain items without prompting
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
# List all identities to find the exact name
debug_log "Listing all identities in the keychain:"
IDENTITY_INFO=$(security find-identity -v "$KEYCHAIN_NAME")
debug_log "$IDENTITY_INFO"
# Parse the exact identity name from the output
EXACT_IDENTITY=$(echo "$IDENTITY_INFO" | grep "Developer ID Application" | head -1 | sed -E 's/.*"(Developer ID Application: .*)"/\1/')
if [[ -n "$EXACT_IDENTITY" ]]; then
debug_log "Found exact identity: $EXACT_IDENTITY"
SIGNING_IDENTITY="$EXACT_IDENTITY"
echo "SIGNING_IDENTITY=$SIGNING_IDENTITY" >> $GITHUB_ENV
echo "CERTIFICATE_AVAILABLE=true" >> $GITHUB_ENV
else
debug_log "WARNING: No Developer ID Application certificate found"
if [[ "false" == "true" ]]; then
debug_log "Falling back to ad-hoc signing"
echo "CERTIFICATE_AVAILABLE=adhoc" >> $GITHUB_ENV
else
debug_log "Not falling back to ad-hoc signing as specified"
echo "CERTIFICATE_AVAILABLE=false" >> $GITHUB_ENV
fi
fi
shell: bash
- name: Sign application
id: sign-app
run: |
# Debug log helper
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
debug_log "Starting application signing process"
# Make sure keychain is unlocked and available
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_NAME"
security list-keychains
security default-keychain
# Verify certificate exists
IDENTITY_INFO=$(security find-identity -v "$KEYCHAIN_NAME")
debug_log "$IDENTITY_INFO"
# Directly extract hash to avoid ambiguity
if [[ "$IDENTITY_INFO" =~ ([0-9A-F]{40}) ]]; then
HASH_ID="${BASH_REMATCH[1]}"
debug_log "Using certificate hash: $HASH_ID"
SIGNING_IDENTITY="$HASH_ID" # Use hash directly
else
# Try to extract certificate name if hash not found
EXACT_IDENTITY=$(echo "$IDENTITY_INFO" | grep "Developer ID Application" | head -1 | sed -E 's/.*"(Developer ID Application: .*)"/\1/')
if [[ -z "$EXACT_IDENTITY" ]]; then
debug_log "ERROR: No Developer ID Application certificate found in keychain"
debug_log "$IDENTITY_INFO"
echo "SIGNING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
debug_log "Using certificate identity: $EXACT_IDENTITY"
SIGNING_IDENTITY="$EXACT_IDENTITY"
fi
# Check entitlements file and validate it
ENTITLEMENTS_PATH="${{ env.ENTITLEMENTS_FILE }}"
USE_ENTITLEMENTS=false
if [[ -f "$ENTITLEMENTS_PATH" ]]; then
debug_log "Found entitlements file: $ENTITLEMENTS_PATH - validating..."
# Try to validate the entitlements file
plutil -lint "$ENTITLEMENTS_PATH" > /dev/null 2>&1
if [ $? -eq 0 ]; then
debug_log "Entitlements file is valid, will use for signing"
USE_ENTITLEMENTS=true
else
debug_log "WARNING: Entitlements file is invalid, will sign without entitlements"
# Print the entitlements file content for debugging
debug_log "Entitlements file content:"
cat "$ENTITLEMENTS_PATH" | tee -a "$DEBUG_LOG_PATH"
fi
else
debug_log "No entitlements file found at $ENTITLEMENTS_PATH, will sign without entitlements"
fi
# Prepare script and crash entitlements paths
SCRIPT_PATH="./scripts/sign_all.sh"
CRASH_ENTITLEMENTS_PATH="./scripts/crash_entitlements.plist"
# Ensure script is executable
chmod +x "$SCRIPT_PATH"
# Log paths
debug_log "Sign script path: $SCRIPT_PATH"
debug_log "Crash entitlements path: $CRASH_ENTITLEMENTS_PATH"
# Verify files exist
if [[ ! -f "$SCRIPT_PATH" ]]; then
debug_log "ERROR: Sign script not found at $SCRIPT_PATH"
ls -la "$(dirname "$SCRIPT_PATH")" | tee -a "$DEBUG_LOG_PATH"
echo "SIGNING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
if [[ ! -f "$CRASH_ENTITLEMENTS_PATH" ]]; then
debug_log "ERROR: Crash entitlements not found at $CRASH_ENTITLEMENTS_PATH"
ls -la "$(dirname "$CRASH_ENTITLEMENTS_PATH")" | tee -a "$DEBUG_LOG_PATH"
echo "SIGNING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
# Run comprehensive signing script
debug_log "Running comprehensive signing script..."
"$SCRIPT_PATH" "$SIGNING_IDENTITY" "$APP_PATH" "$ENTITLEMENTS_PATH" "$CRASH_ENTITLEMENTS_PATH" 2>&1 | tee -a "$DEBUG_LOG_PATH"
SIGN_RESULT=${PIPESTATUS[0]}
if [ $SIGN_RESULT -eq 0 ]; then
debug_log "App signed successfully"
echo "SIGNING_RESULT=true" >> $GITHUB_ENV
else
debug_log "ERROR: App signing failed with exit code: $SIGN_RESULT"
echo "SIGNING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
shell: bash
- name: Notarize application
id: notarize-app
if: env.SIGNING_RESULT == 'true'
run: |
# Debug log helper
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
debug_log "Starting notarization process"
# Create ZIP for notarization
debug_log "Creating ZIP archive for notarization"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
if [ $? -ne 0 ]; then
debug_log "Error creating ZIP archive"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
exit 1
fi
debug_log "ZIP archive created successfully at: $ZIP_PATH"
ZIP_SIZE=$(du -h "$ZIP_PATH" | cut -f1)
debug_log "ZIP archive size: $ZIP_SIZE"
# Save UUID to a file to ensure it persists across steps
UUID_FILE="$WORK_DIR/notarization_uuid.txt"
# Submit for notarization - use separate submission and polling
debug_log "Submitting app for notarization..."
# Submit with error capture
SUBMIT_OUTPUT=$(xcrun notarytool submit "$ZIP_PATH" --key "$API_KEY_FILE" --key-id "${{ secrets.NOTARY_API_KEY_ID }}" --issuer "${{ secrets.NOTARY_API_KEY_ISSUER_ID }}" 2>&1)
SUBMIT_STATUS=$?
# Save output for detailed analysis
echo "$SUBMIT_OUTPUT" > "$WORK_DIR/submit_output.txt"
cat "$WORK_DIR/submit_output.txt" | tee -a "$DEBUG_LOG_PATH"
if [ $SUBMIT_STATUS -ne 0 ]; then
debug_log "ERROR: Failed to submit for notarization, exit code: $SUBMIT_STATUS"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
exit 1
fi
# Extract the request UUID - ensuring we get just one match
REQUEST_UUID=$(echo "$SUBMIT_OUTPUT" | grep -o "id: [a-z0-9-]*" | head -1 | cut -d' ' -f2)
if [ -z "$REQUEST_UUID" ]; then
# Alternative grep pattern
REQUEST_UUID=$(echo "$SUBMIT_OUTPUT" | grep -o "[a-f0-9]\{8\}-[a-f0-9]\{4\}-[a-f0-9]\{4\}-[a-f0-9]\{4\}-[a-f0-9]\{12\}" | head -1)
fi
if [ -z "$REQUEST_UUID" ]; then
debug_log "ERROR: Failed to extract UUID from notarization submission"
debug_log "Full submission output:"
cat "$WORK_DIR/submit_output.txt"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
exit 1
fi
debug_log "Notarization submission UUID: $REQUEST_UUID"
echo "NOTARIZATION_UUID=$REQUEST_UUID" >> $GITHUB_ENV
# Also save UUID to file so it's available in cleanup step
echo "$REQUEST_UUID" > "$UUID_FILE"
debug_log "Saved UUID to file: $UUID_FILE"
# Wait for notarization to complete with polling
debug_log "Waiting for notarization to complete (this may take several minutes)..."
WAIT_COUNTER=1
TOTAL_WAIT=60 # 60 minutes maximum
NOTARIZATION_COMPLETED=false
while [ $WAIT_COUNTER -le $TOTAL_WAIT ]; do
if [ $WAIT_COUNTER -gt 1 ]; then
debug_log "Waiting 60 seconds before checking again (attempt $WAIT_COUNTER/$TOTAL_WAIT)..."
sleep 60
fi
# Check status - make sure UUID is clean and not duplicated
STATUS_OUTPUT=$(xcrun notarytool info "$REQUEST_UUID" --key "$API_KEY_FILE" --key-id "${{ secrets.NOTARY_API_KEY_ID }}" --issuer "${{ secrets.NOTARY_API_KEY_ISSUER_ID }}" 2>&1)
STATUS_CODE=$?
echo "$STATUS_OUTPUT" > "$WORK_DIR/status_output_$WAIT_COUNTER.txt"
cat "$WORK_DIR/status_output_$WAIT_COUNTER.txt" | tee -a "$DEBUG_LOG_PATH"
if [ $STATUS_CODE -ne 0 ]; then
debug_log "WARNING: Status check failed, exit code: $STATUS_CODE"
# Continue anyway to retry
else
# Extract status
REQUEST_STATUS=$(echo "$STATUS_OUTPUT" | grep -o "status: [A-Za-z]*" | cut -d' ' -f2)
if [ -z "$REQUEST_STATUS" ]; then
debug_log "WARNING: Could not extract status from output"
else
debug_log "Notarization status: $REQUEST_STATUS"
if [ "$REQUEST_STATUS" = "Accepted" ]; then
debug_log "Notarization successful!"
NOTARIZATION_COMPLETED=true
echo "NOTARIZATION_RESULT=true" >> $GITHUB_ENV
echo "NOTARIZATION_COMPLETED=true" >> $GITHUB_ENV
break
elif [ "$REQUEST_STATUS" = "Invalid" ] || [ "$REQUEST_STATUS" = "Rejected" ]; then
debug_log "ERROR: Notarization failed with status: $REQUEST_STATUS"
NOTARIZATION_COMPLETED=true
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
echo "NOTARIZATION_COMPLETED=true" >> $GITHUB_ENV
# Get the log URL to diagnose the issue
LOG_URL_OUTPUT=$(xcrun notarytool log "$REQUEST_UUID" --key "$API_KEY_FILE" --key-id "${{ secrets.NOTARY_API_KEY_ID }}" --issuer "${{ secrets.NOTARY_API_KEY_ISSUER_ID }}" 2>&1)
echo "Notarization log:" | tee -a "$DEBUG_LOG_PATH"
echo "$LOG_URL_OUTPUT" | tee -a "$DEBUG_LOG_PATH"
exit 1
fi
# In progress - continue waiting
fi
fi
WAIT_COUNTER=$((WAIT_COUNTER+1))
done
# Check if we timed out
if [ "$NOTARIZATION_COMPLETED" != "true" ]; then
debug_log "ERROR: Notarization timed out after $TOTAL_WAIT attempts"
echo "NOTARIZATION_RESULT=timeout" >> $GITHUB_ENV
echo "NOTARIZATION_COMPLETED=true" >> $GITHUB_ENV
exit 1
fi
if [ "$REQUEST_STATUS" != "Accepted" ]; then
debug_log "ERROR: Notarization failed with status: $REQUEST_STATUS"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
exit 1
fi
# Success - now staple the ticket
debug_log "Notarization complete, proceeding to staple the ticket"
xcrun stapler staple "$APP_PATH"
STAPLE_RESULT=$?
if [ $STAPLE_RESULT -eq 0 ]; then
debug_log "Notarization ticket stapled successfully"
echo "STAPLING_RESULT=true" >> $GITHUB_ENV
# Verify stapling
xcrun stapler validate "$APP_PATH"
VALIDATE_RESULT=$?
if [ $VALIDATE_RESULT -eq 0 ]; then
debug_log "Stapling validation successful"
echo "VERIFY_RESULT=true" >> $GITHUB_ENV
else
debug_log "WARNING: Stapling validation failed but continuing"
echo "VERIFY_RESULT=false" >> $GITHUB_ENV
fi
else
debug_log "ERROR: Failed to staple notarization ticket"
echo "STAPLING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
# Mark this step as having completed successfully for the cleanup step
echo "NOTARIZE_STEP_COMPLETED=true" >> $GITHUB_ENV
shell: bash
- name: Clean up
id: cleanup
if: always()
run: |
# Debug log helper
function debug_log() {
echo "DEBUG: $1"
if [[ -n "$DEBUG_LOG_PATH" ]]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$DEBUG_LOG_PATH"
fi
}
debug_log "Starting cleanup process..."
# Check if notarization is still in progress
if [[ "$NOTARIZE_STEP_COMPLETED" != "true" && -n "$WORK_DIR" && -f "$WORK_DIR/notarization_uuid.txt" ]]; then
debug_log "WARNING: Notarization step did not complete properly. Checking status before cleanup."
# Read UUID from file
REQUEST_UUID=$(cat "$WORK_DIR/notarization_uuid.txt")
if [[ -n "$REQUEST_UUID" ]]; then
debug_log "Found notarization UUID: $REQUEST_UUID"
debug_log "Will check status one more time before cleanup..."
if [[ -f "$API_KEY_FILE" ]]; then
STATUS_OUTPUT=$(xcrun notarytool info "$REQUEST_UUID" --key "$API_KEY_FILE" --key-id "${{ secrets.NOTARY_API_KEY_ID }}" --issuer "${{ secrets.NOTARY_API_KEY_ISSUER_ID }}" 2>&1 || echo "Status check failed")
debug_log "Final notarization status check output:"
debug_log "$STATUS_OUTPUT"
else
debug_log "API key file not available for final status check"
fi
else
debug_log "No UUID file found, skipping final status check"
fi
else
debug_log "Notarization process already completed or not started"
fi
# Save notarization logs if available
if [[ -d "$WORK_DIR" ]]; then
debug_log "Saving notarization logs from work directory"
mkdir -p "$DEBUG_LOG_PATH/../notarization_details" 2>/dev/null || true
cp "$WORK_DIR/"*.txt "$DEBUG_LOG_PATH/../notarization_details/" 2>/dev/null || true
fi
# Clean up keychain
if [[ -n "$KEYCHAIN_NAME" ]]; then
debug_log "Deleting keychain: $KEYCHAIN_NAME"
security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
debug_log "Keychain deleted"
fi
# Clean up temporary files
if [[ -d "$WORK_DIR" ]]; then
debug_log "Removing temporary work directory: $WORK_DIR"
rm -rf "$WORK_DIR" 2>/dev/null || true
debug_log "Temporary files deleted"
fi
debug_log "Cleanup completed"
shell: bash
# Upload debug logs if available
- name: Upload Debug Logs
uses: actions/upload-artifact@v3
if: always()
# Use the macos-notarize action to sign and notarize the app
- name: Sign and Notarize macOS App
uses: ./.gitea/actions/macos-notarize
id: sign-and-notarize
with:
name: notarize-debug-logs
path: debug_logs
retention-days: 7
app-path: ${{ env.APP_PATH }}
entitlements-file: ${{ env.ENTITLEMENTS_FILE }}
team-id: ${{ secrets.APPLE_TEAM_ID }}
certificate-base64: ${{ secrets.MACOS_CERTIFICATE }}
certificate-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
notarization-method: 'api-key'
notary-api-key-id: ${{ secrets.NOTARY_API_KEY_ID }}
notary-api-key-issuer-id: ${{ secrets.NOTARY_API_KEY_ISSUER_ID }}
notary-api-key-path: ${{ secrets.NOTARY_API_KEY_PATH }}
bundle-id: ${{ env.BUNDLE_ID }}
fallback-to-adhoc: 'false'
# Upload only the DMG file as main distribution artifact
- name: Upload Mac Distribution DMG
# Upload stapled app directly (this is the most reliable approach)
- name: Upload Stapled App Bundle
uses: actions/upload-artifact@v3
if: env.NOTARIZED_STATUS == 'true' && env.SIGNED_STATUS != 'none'
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none'
with:
name: LuckyWorld-Mac-Distribution
path: ${{ env.PACKAGE_PATH }}
name: LuckyWorld-macOS-Stapled-App-Bundle
path: ${{ env.APP_PATH }}
retention-days: 30
# Upload only the DMG file from the macos-notarize action
- name: Upload Stapled App DMG
uses: actions/upload-artifact@v3
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none'
with:
name: LuckyWorld-macOS-Signed-Notarized-DMG
path: ${{ steps.sign-and-notarize.outputs.package-path }}
retention-days: 30
# Report results
- name: Report Results
run: |
echo "🔐 App signing: ${{ env.SIGNED_STATUS }}"
echo "🔏 App notarization: ${{ env.NOTARIZED_STATUS }}"
echo "🔐 App signing: ${{ steps.sign-and-notarize.outputs.signed }}"
echo "🔏 App notarization: ${{ steps.sign-and-notarize.outputs.notarized }}"
if [ "${{ env.SIGNED_STATUS }}" != "none" ]; then
if [ "${{ steps.sign-and-notarize.outputs.signed }}" != "none" ]; then
echo "✅ Packaging completed successfully!"
echo "Final package: ${{ env.PACKAGE_PATH }}"
echo "Final package: ${{ steps.sign-and-notarize.outputs.package-path }}"
else
echo "⚠️ App was not signed - check the logs for details"
fi

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<!-- Not including get-task-allow permission -->
</dict>
</plist>

View File

@ -1,148 +0,0 @@
#!/bin/bash
# Parametreleri al
SIGNING_IDENTITY="$1"
APP_PATH="$2"
ENTITLEMENTS_PATH="$3"
CRASH_ENTITLEMENTS_PATH="$4"
# Sertifika hash'ini ayıkla (varsa)
CERT_HASH=$(echo "$SIGNING_IDENTITY" | grep -o '[0-9A-F]\{40\}')
if [ -n "$CERT_HASH" ]; then
echo "📝 Using certificate hash: $CERT_HASH"
SIGNING_ID="$CERT_HASH"
else
echo "📝 Using certificate identity: $SIGNING_IDENTITY"
SIGNING_ID="$SIGNING_IDENTITY"
fi
echo "📝 Comprehensive signing starting..."
echo "App Path: $APP_PATH"
echo "Signing Identity: $SIGNING_ID"
echo "Entitlements: $ENTITLEMENTS_PATH"
echo "CrashReporter Entitlements: $CRASH_ENTITLEMENTS_PATH"
# Step 1: Tüm dylib dosyalarını imzala (küçük gruplar halinde)
echo "🔍 Signing all dylib files..."
find "$APP_PATH" -name "*.dylib" | while read -r dylib; do
echo "Signing: $dylib"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$dylib" || echo "⚠️ Failed to sign: $dylib"
done
# Step 2: Tüm .so dosyalarını imzala
echo "🔍 Signing all .so files..."
find "$APP_PATH" -name "*.so" | while read -r so; do
echo "Signing: $so"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$so" || echo "⚠️ Failed to sign: $so"
done
# Step 3: Tüm yürütülebilir dosyaları imzala
echo "🔍 Signing all executable files..."
find "$APP_PATH" -type f -perm +111 -not -path "*.framework/*" -not -name "*.dylib" -not -name "*.so" | while read -r exe; do
echo "Signing: $exe"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$exe" || echo "⚠️ Failed to sign: $exe"
done
# Step 4: Tüm framework'leri imzala
echo "🔍 Signing all frameworks..."
find "$APP_PATH" -path "*.framework" -type d | while read -r framework; do
echo "Signing framework: $framework"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$framework" || echo "⚠️ Failed to sign: $framework"
done
# Step 5: CrashReportClient'ı özel olarak imzala
echo "🔍 Looking for CrashReportClient.app..."
CRASH_REPORTER_PATHS=$(find "$APP_PATH" -path "*CrashReportClient.app" -type d)
if [ -n "$CRASH_REPORTER_PATHS" ]; then
echo "✅ Found CrashReportClient apps:"
echo "$CRASH_REPORTER_PATHS"
for CRASH_REPORTER in $CRASH_REPORTER_PATHS; do
echo "🔐 Special signing for CrashReportClient: $CRASH_REPORTER"
# CrashReporter içindeki executable'ları imzala
find "$CRASH_REPORTER" -type f -perm +111 | while read -r crash_exe; do
echo "Signing CrashReporter binary: $crash_exe"
codesign --force --options runtime --timestamp --entitlements "$CRASH_ENTITLEMENTS_PATH" --sign "$SIGNING_ID" "$crash_exe" || echo "⚠️ Failed to sign: $crash_exe"
done
# CrashReporter bundle'ı imzala
echo "Signing CrashReporter bundle: $CRASH_REPORTER"
codesign --force --deep --options runtime --timestamp --entitlements "$CRASH_ENTITLEMENTS_PATH" --sign "$SIGNING_ID" "$CRASH_REPORTER" || echo "⚠️ Failed to sign CrashReportClient bundle"
# İmzayı doğrula
echo "Verifying CrashReportClient signature..."
codesign -vvv "$CRASH_REPORTER" || echo "⚠️ CrashReporter signature verification failed"
done
else
echo "⚠️ No CrashReportClient.app found in $APP_PATH"
fi
# Step 6: Boost kütüphaneleri özellikle imzala
echo "🔍 Looking for Boost libraries..."
BOOST_LIBS=$(find "$APP_PATH" -path "*/UE/LuckyWorld/Binaries/Mac/*.dylib")
if [ -n "$BOOST_LIBS" ]; then
echo "✅ Found Boost libs, specifically signing them..."
for lib in $BOOST_LIBS; do
echo "Signing boost lib: $lib"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$lib" || echo "⚠️ Failed to sign: $lib"
done
else
echo "⚠️ No Boost libraries found"
fi
# Step 7: Engine ThirdParty kütüphanelerini imzala
echo "🔍 Looking for Engine ThirdParty libraries..."
THIRD_PARTY_PATHS=$(find "$APP_PATH" -path "*/Engine/Binaries/ThirdParty" -type d)
if [ -n "$THIRD_PARTY_PATHS" ]; then
echo "✅ Found ThirdParty directories:"
echo "$THIRD_PARTY_PATHS"
for THIRD_PARTY in $THIRD_PARTY_PATHS; do
echo "Processing ThirdParty directory: $THIRD_PARTY"
find "$THIRD_PARTY" -name "*.dylib" | while read -r engine_lib; do
echo "Signing ThirdParty lib: $engine_lib"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$engine_lib" || echo "⚠️ Failed to sign: $engine_lib"
done
done
else
echo "⚠️ No ThirdParty directories found"
fi
# Step 8: Plugin kütüphanelerini imzala
echo "🔍 Looking for Plugin libraries..."
PLUGIN_PATHS=$(find "$APP_PATH" -path "*/Engine/Plugins" -type d)
if [ -n "$PLUGIN_PATHS" ]; then
echo "✅ Found Plugin directories:"
echo "$PLUGIN_PATHS"
for PLUGIN_PATH in $PLUGIN_PATHS; do
echo "Processing Plugin directory: $PLUGIN_PATH"
find "$PLUGIN_PATH" -name "*.dylib" | while read -r plugin_lib; do
echo "Signing Plugin lib: $plugin_lib"
codesign --force --options runtime --timestamp --sign "$SIGNING_ID" "$plugin_lib" || echo "⚠️ Failed to sign: $plugin_lib"
done
done
else
echo "⚠️ No Plugin directories found"
fi
# Step 9: Diğer nested app bundles imzala
echo "🔍 Signing nested app bundles..."
find "$APP_PATH" -path "*.app" -type d | grep -v CrashReportClient | while read -r nested_app; do
if [ "$nested_app" != "$APP_PATH" ]; then
echo "Signing nested app: $nested_app"
codesign --force --deep --options runtime --timestamp --entitlements "$ENTITLEMENTS_PATH" --sign "$SIGNING_ID" "$nested_app" || echo "⚠️ Failed to sign: $nested_app"
fi
done
# Step 10: Ana uygulamayı imzala
echo "🔐 Final signing of the main app bundle..."
codesign --force --deep --options runtime --timestamp --entitlements "$ENTITLEMENTS_PATH" --sign "$SIGNING_ID" "$APP_PATH" || { echo "❌ ERROR: Main app signing failed"; exit 1; }
# İmzalamayı doğrula
echo "🔍 Verifying main app signature..."
codesign -dvv "$APP_PATH" || { echo "❌ ERROR: Main app signature verification failed"; exit 1; }
echo "✅ Comprehensive signing completed successfully"
exit 0