From f1c3e9da5a2dabde438d28cc73d4b413000882be Mon Sep 17 00:00:00 2001 From: Ozgur Ersoy Date: Wed, 16 Apr 2025 21:45:15 +0200 Subject: [PATCH] fix(actions): enhance macOS notarization workflow by simplifying action structure, removing unnecessary debug logging steps, and implementing custom DMG creation with installer script --- .gitea/actions/macos-notarize/action.yml | 3 +- .gitea/workflows/test-macos-build.yml | 619 ++--------------------- scripts/crash_entitlements.plist | 17 - scripts/sign_all.sh | 148 ------ 4 files changed, 38 insertions(+), 749 deletions(-) delete mode 100644 scripts/crash_entitlements.plist delete mode 100644 scripts/sign_all.sh diff --git a/.gitea/actions/macos-notarize/action.yml b/.gitea/actions/macos-notarize/action.yml index 36c3e52e..aed5c6cd 100644 --- a/.gitea/actions/macos-notarize/action.yml +++ b/.gitea/actions/macos-notarize/action.yml @@ -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" - \ No newline at end of file diff --git a/.gitea/workflows/test-macos-build.yml b/.gitea/workflows/test-macos-build.yml index a29dc422..bbf2e560 100644 --- a/.gitea/workflows/test-macos-build.yml +++ b/.gitea/workflows/test-macos-build.yml @@ -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: | @@ -151,589 +144,51 @@ jobs: echo "Found entitlements file: ${{ env.ENTITLEMENTS_FILE }}" 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() - with: - name: notarize-debug-logs - path: debug_logs - retention-days: 7 - # Upload only the DMG file as main distribution artifact - - name: Upload Mac Distribution DMG - uses: actions/upload-artifact@v3 - if: env.NOTARIZED_STATUS == 'true' && env.SIGNED_STATUS != 'none' + # 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: LuckyWorld-Mac-Distribution - path: ${{ env.PACKAGE_PATH }} - retention-days: 30 + 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 stapled app directly (this is the most reliable approach) + - name: Upload Stapled App Bundle + uses: actions/upload-artifact@v3 + if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' + with: + 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 diff --git a/scripts/crash_entitlements.plist b/scripts/crash_entitlements.plist deleted file mode 100644 index e437d0b4..00000000 --- a/scripts/crash_entitlements.plist +++ /dev/null @@ -1,17 +0,0 @@ - - - - - com.apple.security.cs.allow-jit - - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-library-validation - - com.apple.security.automation.apple-events - - com.apple.security.cs.disable-executable-page-protection - - - - \ No newline at end of file diff --git a/scripts/sign_all.sh b/scripts/sign_all.sh deleted file mode 100644 index 19cab6ea..00000000 --- a/scripts/sign_all.sh +++ /dev/null @@ -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 \ No newline at end of file