fix(actions): enhance macOS notarization workflow by improving input descriptions, adding detailed logging, and refining signing and notarization processes for better error handling and traceability
Some checks failed
Test macOS Build Action / test-macos-build (push) Failing after 40m26s

This commit is contained in:
Ozgur 2025-04-16 19:03:33 +02:00
parent dd01055e1e
commit 835074f332
No known key found for this signature in database
GPG Key ID: 66CDF27505A35546
2 changed files with 798 additions and 762 deletions

File diff suppressed because it is too large Load Diff

View File

@ -561,15 +561,14 @@ jobs:
ZIP_SIZE=$(du -h "$ZIP_PATH" | cut -f1) ZIP_SIZE=$(du -h "$ZIP_PATH" | cut -f1)
debug_log "ZIP archive size: $ZIP_SIZE" 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 # Submit for notarization - use separate submission and polling
debug_log "Submitting app for notarization..." debug_log "Submitting app for notarization..."
# Create submission file command from parts to avoid shell re-interpretation
SUBMIT_CMD="xcrun notarytool submit \"$ZIP_PATH\" --key \"$API_KEY_FILE\" --key-id \"${{ secrets.NOTARY_API_KEY_ID }}\" --issuer \"${{ secrets.NOTARY_API_KEY_ISSUER_ID }}\""
debug_log "Running command: $SUBMIT_CMD"
# Submit with error capture # Submit with error capture
SUBMIT_OUTPUT=$(eval "$SUBMIT_CMD" 2>&1) 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=$? SUBMIT_STATUS=$?
# Save output for detailed analysis # Save output for detailed analysis
@ -582,12 +581,12 @@ jobs:
exit 1 exit 1
fi fi
# Extract the request UUID (handle different output formats) # Extract the request UUID - ensuring we get just one match
REQUEST_UUID=$(echo "$SUBMIT_OUTPUT" | grep -o "id: [a-z0-9-]*" | cut -d' ' -f2) REQUEST_UUID=$(echo "$SUBMIT_OUTPUT" | grep -o "id: [a-z0-9-]*" | head -1 | cut -d' ' -f2)
if [ -z "$REQUEST_UUID" ]; then if [ -z "$REQUEST_UUID" ]; then
# Alternative grep pattern # 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\}") 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 fi
if [ -z "$REQUEST_UUID" ]; then if [ -z "$REQUEST_UUID" ]; then
@ -601,11 +600,16 @@ jobs:
debug_log "Notarization submission UUID: $REQUEST_UUID" debug_log "Notarization submission UUID: $REQUEST_UUID"
echo "NOTARIZATION_UUID=$REQUEST_UUID" >> $GITHUB_ENV 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 # Wait for notarization to complete with polling
debug_log "Waiting for notarization to complete (this may take several minutes)..." debug_log "Waiting for notarization to complete (this may take several minutes)..."
WAIT_COUNTER=1 WAIT_COUNTER=1
TOTAL_WAIT=60 # 60 minutes maximum TOTAL_WAIT=60 # 60 minutes maximum
NOTARIZATION_COMPLETED=false
while [ $WAIT_COUNTER -le $TOTAL_WAIT ]; do while [ $WAIT_COUNTER -le $TOTAL_WAIT ]; do
if [ $WAIT_COUNTER -gt 1 ]; then if [ $WAIT_COUNTER -gt 1 ]; then
@ -613,10 +617,8 @@ jobs:
sleep 60 sleep 60
fi fi
# Check status # Check status - make sure UUID is clean and not duplicated
STATUS_CMD="xcrun notarytool info \"$REQUEST_UUID\" --key \"$API_KEY_FILE\" --key-id \"${{ secrets.NOTARY_API_KEY_ID }}\" --issuer \"${{ secrets.NOTARY_API_KEY_ISSUER_ID }}\"" 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)
debug_log "Checking status with: $STATUS_CMD"
STATUS_OUTPUT=$(eval "$STATUS_CMD" 2>&1)
STATUS_CODE=$? STATUS_CODE=$?
echo "$STATUS_OUTPUT" > "$WORK_DIR/status_output_$WAIT_COUNTER.txt" echo "$STATUS_OUTPUT" > "$WORK_DIR/status_output_$WAIT_COUNTER.txt"
@ -636,11 +638,21 @@ jobs:
if [ "$REQUEST_STATUS" = "Accepted" ]; then if [ "$REQUEST_STATUS" = "Accepted" ]; then
debug_log "Notarization successful!" debug_log "Notarization successful!"
NOTARIZATION_COMPLETED=true
echo "NOTARIZATION_RESULT=true" >> $GITHUB_ENV echo "NOTARIZATION_RESULT=true" >> $GITHUB_ENV
echo "NOTARIZATION_COMPLETED=true" >> $GITHUB_ENV
break break
elif [ "$REQUEST_STATUS" = "Invalid" ] || [ "$REQUEST_STATUS" = "Rejected" ]; then elif [ "$REQUEST_STATUS" = "Invalid" ] || [ "$REQUEST_STATUS" = "Rejected" ]; then
debug_log "ERROR: Notarization failed with status: $REQUEST_STATUS" debug_log "ERROR: Notarization failed with status: $REQUEST_STATUS"
NOTARIZATION_COMPLETED=true
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV 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 exit 1
fi fi
# In progress - continue waiting # In progress - continue waiting
@ -650,15 +662,16 @@ jobs:
WAIT_COUNTER=$((WAIT_COUNTER+1)) WAIT_COUNTER=$((WAIT_COUNTER+1))
done done
# Check final status # Check if we timed out
if [ $WAIT_COUNTER -gt $TOTAL_WAIT ]; then if [ "$NOTARIZATION_COMPLETED" != "true" ]; then
debug_log "ERROR: Notarization wait timeout after $TOTAL_WAIT minutes" debug_log "ERROR: Notarization timed out after $TOTAL_WAIT attempts"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV echo "NOTARIZATION_RESULT=timeout" >> $GITHUB_ENV
echo "NOTARIZATION_COMPLETED=true" >> $GITHUB_ENV
exit 1 exit 1
fi fi
if [ "$REQUEST_STATUS" != "Accepted" ]; then if [ "$REQUEST_STATUS" != "Accepted" ]; then
debug_log "ERROR: Notarization failed or timed out" debug_log "ERROR: Notarization failed with status: $REQUEST_STATUS"
echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV echo "NOTARIZATION_RESULT=false" >> $GITHUB_ENV
exit 1 exit 1
fi fi
@ -688,128 +701,9 @@ jobs:
echo "STAPLING_RESULT=false" >> $GITHUB_ENV echo "STAPLING_RESULT=false" >> $GITHUB_ENV
exit 1 exit 1
fi fi
shell: bash
- name: Staple notarization ticket # Mark this step as having completed successfully for the cleanup step
id: staple-ticket echo "NOTARIZE_STEP_COMPLETED=true" >> $GITHUB_ENV
if: env.SIGNING_RESULT == 'true' && env.NOTARIZATION_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 "Stapling notarization ticket to app"
# 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
else
debug_log "ERROR: Stapling failed with exit code: $STAPLE_RESULT"
echo "STAPLING_RESULT=false" >> $GITHUB_ENV
exit 1
fi
shell: bash
- name: Verify notarization and stapling
id: verify-notarization
if: env.SIGNING_RESULT == 'true' && env.NOTARIZATION_RESULT == 'true' && env.STAPLING_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 "Verifying notarization and stapling"
# Verify code signature with staple
debug_log "Verifying code signature..."
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
VERIFY_RESULT=$?
if [ $VERIFY_RESULT -eq 0 ]; then
debug_log "Code signature verification successful"
else
debug_log "ERROR: Code signature verification failed with exit code: $VERIFY_RESULT"
exit 1
fi
# Verify stapling
debug_log "Verifying stapling..."
xcrun stapler validate "$APP_PATH"
STAPLE_VERIFY_RESULT=$?
if [ $STAPLE_VERIFY_RESULT -eq 0 ]; then
debug_log "Stapling verification successful"
echo "VERIFY_RESULT=true" >> $GITHUB_ENV
else
debug_log "ERROR: Stapling verification failed with exit code: $STAPLE_VERIFY_RESULT"
echo "VERIFY_RESULT=false" >> $GITHUB_ENV
exit 1
fi
shell: bash
- name: Remove quarantine attribute
id: remove-quarantine
if: env.SIGNING_RESULT == 'true' && env.NOTARIZATION_RESULT == 'true' && env.STAPLING_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 "Removing quarantine attribute from app"
# Directly run the command without creating a script file
debug_log "Removing quarantine attribute from all files..."
find "$APP_PATH" -exec xattr -d com.apple.quarantine {} \; 2>/dev/null || true
debug_log "Quarantine attributes removed"
shell: bash
- name: Package signed app
id: package-app
if: env.SIGNING_RESULT == 'true' && env.NOTARIZATION_RESULT == 'true' && env.STAPLING_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 "Packaging the signed and notarized app"
# Create DMG using hdiutil
debug_log "Creating DMG package..."
hdiutil create -volname "$APP_NAME" -srcfolder "$APP_PATH" -ov -format UDZO "$DMG_PATH"
DMG_CREATE_RESULT=$?
# Check DMG creation result
if [ $DMG_CREATE_RESULT -eq 0 ]; then
debug_log "DMG package created successfully at: $DMG_PATH"
DMG_SIZE=$(du -h "$DMG_PATH" | cut -f1)
debug_log "DMG size: $DMG_SIZE"
echo "DMG_CREATED=true" >> $GITHUB_ENV
echo "PACKAGE_PATH=$DMG_PATH" >> $GITHUB_ENV
else
debug_log "WARNING: DMG creation failed, using ZIP as distribution package"
echo "DMG_CREATED=false" >> $GITHUB_ENV
echo "PACKAGE_PATH=$ZIP_PATH" >> $GITHUB_ENV
fi
shell: bash shell: bash
- name: Clean up - name: Clean up
@ -824,30 +718,51 @@ jobs:
fi fi
} }
debug_log "Cleaning up resources" debug_log "Starting cleanup process..."
# Save state message for better debugging # Check if notarization is still in progress
if [[ "$NOTARIZATION_RESULT" == "true" ]]; then if [[ "$NOTARIZE_STEP_COMPLETED" != "true" && -n "$WORK_DIR" && -f "$WORK_DIR/notarization_uuid.txt" ]]; then
debug_log "Cleanup after successful notarization" 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 else
debug_log "Cleanup after notarization state: $NOTARIZATION_RESULT" 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 fi
# Clean up keychain # Clean up keychain
if [[ -n "$KEYCHAIN_NAME" ]]; then if [[ -n "$KEYCHAIN_NAME" ]]; then
security delete-keychain "$KEYCHAIN_NAME" || true debug_log "Deleting keychain: $KEYCHAIN_NAME"
security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
debug_log "Keychain deleted" debug_log "Keychain deleted"
fi fi
# Clean up temporary files # Clean up temporary files
if [[ -d "$WORK_DIR" ]]; then if [[ -d "$WORK_DIR" ]]; then
# Save notarization logs first debug_log "Removing temporary work directory: $WORK_DIR"
if [[ -d "$DEBUG_LOG_PATH" ]] && [[ -d "$WORK_DIR" ]]; then rm -rf "$WORK_DIR" 2>/dev/null || true
debug_log "Saving work directory files to debug logs"
cp -R "$WORK_DIR/"*.txt "$DEBUG_LOG_PATH/" 2>/dev/null || true
fi
rm -rf "$WORK_DIR" || true
debug_log "Temporary files deleted" debug_log "Temporary files deleted"
fi fi