fix(actions): enhance macOS notarization script with verification steps and DMG package creation
All checks were successful
Test macOS Build Action / test-macos-build (push) Successful in 46m3s

This commit is contained in:
Ozgur 2025-04-14 23:43:42 +02:00
parent 64226b067c
commit 574a17e357
No known key found for this signature in database
GPG Key ID: 66CDF27505A35546
2 changed files with 83 additions and 6 deletions

View File

@ -396,11 +396,29 @@ runs:
# Staple the notarization ticket # Staple the notarization ticket
echo "Stapling notarization ticket..." echo "Stapling notarization ticket..."
xcrun stapler staple "${{ inputs.app-path }}" xcrun stapler staple -v "${{ inputs.app-path }}"
STAPLE_STATUS=$? STAPLE_STATUS=$?
if [ $STAPLE_STATUS -eq 0 ]; then if [ $STAPLE_STATUS -eq 0 ]; then
echo "✅ Stapling completed successfully!" echo "✅ Stapling completed successfully!"
# Verify the stapling worked properly
echo "Verifying stapled ticket is properly attached..."
xcrun stapler validate -v "${{ inputs.app-path }}"
# Check if stapling metadata is correctly stored in xattr
echo "Checking app extended attributes..."
if command -v xattr &> /dev/null; then
xattr "${{ inputs.app-path }}" | grep -q "com.apple.provenance" || echo "⚠️ Warning: com.apple.provenance attribute not found"
fi
# Add special instructions for distribution
echo "📋 IMPORTANT DISTRIBUTION NOTE: When users download this app, they may still see Gatekeeper warnings."
echo "This happens because of the 'quarantine' extended attribute that browsers add to downloaded files."
echo "For proper distribution, consider the following options:"
echo "1. Use a DMG installer with a signed, notarized app inside"
echo "2. Add instructions for users on how to open a quarantined app (right-click > Open)"
echo "3. If distributing directly, use a distribution platform that preserves notarization tickets"
else else
echo "⚠️ Stapling completed with status $STAPLE_STATUS (may still be valid)" echo "⚠️ Stapling completed with status $STAPLE_STATUS (may still be valid)"
fi fi
@ -556,11 +574,29 @@ runs:
# Staple the notarization ticket # Staple the notarization ticket
echo "Stapling notarization ticket..." echo "Stapling notarization ticket..."
xcrun stapler staple "${{ inputs.app-path }}" xcrun stapler staple -v "${{ inputs.app-path }}"
STAPLE_STATUS=$? STAPLE_STATUS=$?
if [ $STAPLE_STATUS -eq 0 ]; then if [ $STAPLE_STATUS -eq 0 ]; then
echo "✅ Stapling completed successfully!" echo "✅ Stapling completed successfully!"
# Verify the stapling worked properly
echo "Verifying stapled ticket is properly attached..."
xcrun stapler validate -v "${{ inputs.app-path }}"
# Check if stapling metadata is correctly stored in xattr
echo "Checking app extended attributes..."
if command -v xattr &> /dev/null; then
xattr "${{ inputs.app-path }}" | grep -q "com.apple.provenance" || echo "⚠️ Warning: com.apple.provenance attribute not found"
fi
# Add special instructions for distribution
echo "📋 IMPORTANT DISTRIBUTION NOTE: When users download this app, they may still see Gatekeeper warnings."
echo "This happens because of the 'quarantine' extended attribute that browsers add to downloaded files."
echo "For proper distribution, consider the following options:"
echo "1. Use a DMG installer with a signed, notarized app inside"
echo "2. Add instructions for users on how to open a quarantined app (right-click > Open)"
echo "3. If distributing directly, use a distribution platform that preserves notarization tickets"
else else
echo "⚠️ Stapling completed with status $STAPLE_STATUS (may still be valid)" echo "⚠️ Stapling completed with status $STAPLE_STATUS (may still be valid)"
fi fi
@ -626,18 +662,50 @@ runs:
APP_NAME=$(basename "${{ inputs.app-path }}" .app) APP_NAME=$(basename "${{ inputs.app-path }}" .app)
if [ "${{ steps.notarize.outputs.notarized }}" = "true" ]; then if [ "${{ steps.notarize.outputs.notarized }}" = "true" ]; then
ZIP_FILE="${APP_NAME}-Signed-Notarized.zip" PACKAGE_SUFFIX="Signed-Notarized"
echo "Creating distribution package with notarized app..." echo "Creating distribution package with notarized app..."
else else
ZIP_FILE="${APP_NAME}-Signed.zip" PACKAGE_SUFFIX="Signed"
echo "Creating distribution package with signed app..." echo "Creating distribution package with signed app..."
fi fi
# Create zip package # Create zip package
ZIP_FILE="${APP_NAME}-${PACKAGE_SUFFIX}.zip"
ditto -c -k --keepParent "${{ inputs.app-path }}" "$ZIP_FILE" ditto -c -k --keepParent "${{ inputs.app-path }}" "$ZIP_FILE"
echo "✅ Created ZIP package: $ZIP_FILE"
echo "✅ Created package: $ZIP_FILE" # Check if we can create DMG (hdiutil is available)
echo "::set-output name=package-path::$ZIP_FILE" if command -v hdiutil &> /dev/null; then
# Create DMG package (much better for distribution)
DMG_FILE="${APP_NAME}-${PACKAGE_SUFFIX}.dmg"
echo "Creating DMG distribution package..."
# Create temporary folder for DMG contents
DMG_TMP_DIR=$(mktemp -d)
cp -R "${{ inputs.app-path }}" "$DMG_TMP_DIR/"
# Optional: Add README or instructions
echo "# Installation Instructions\n\nDrag the application to your Applications folder to install." > "$DMG_TMP_DIR/README.txt"
# Create DMG file with the app
hdiutil create -volname "${APP_NAME}" -srcfolder "$DMG_TMP_DIR" -ov -format UDZO "$DMG_FILE"
if [ -f "$DMG_FILE" ]; then
echo "✅ Created DMG package: $DMG_FILE"
# Use DMG as the primary package if available
echo "::set-output name=package-path::$DMG_FILE"
echo "::set-output name=zip-package-path::$ZIP_FILE"
else
echo "⚠️ Failed to create DMG, falling back to ZIP package"
echo "::set-output name=package-path::$ZIP_FILE"
fi
# Clean up temp directory
rm -rf "$DMG_TMP_DIR"
else
echo "hdiutil not available, skipping DMG creation"
echo "::set-output name=package-path::$ZIP_FILE"
fi
- name: Cleanup - name: Cleanup
if: always() if: always()

View File

@ -201,6 +201,15 @@ jobs:
name: ${{ steps.sign-and-notarize.outputs.notarized == 'true' && 'LuckyWorld-macOS-Signed-Notarized' || 'LuckyWorld-macOS-Signed' }} name: ${{ steps.sign-and-notarize.outputs.notarized == 'true' && 'LuckyWorld-macOS-Signed-Notarized' || 'LuckyWorld-macOS-Signed' }}
path: ${{ steps.sign-and-notarize.outputs.package-path }} path: ${{ steps.sign-and-notarize.outputs.package-path }}
retention-days: 30 retention-days: 30
# Upload ZIP package if DMG was created (as a backup)
- name: Upload ZIP Package
uses: actions/upload-artifact@v3
if: steps.sign-and-notarize.outputs.signed != 'none' && steps.sign-and-notarize.outputs.zip-package-path != ''
with:
name: ${{ steps.sign-and-notarize.outputs.notarized == 'true' && 'LuckyWorld-macOS-Signed-Notarized-ZIP' || 'LuckyWorld-macOS-Signed-ZIP' }}
path: ${{ steps.sign-and-notarize.outputs.zip-package-path }}
retention-days: 30
# Report results # Report results
- name: Report Results - name: Report Results