LuckyWorld/.gitea/workflows/test-local-signing.yml
Ozgur Ersoy 567ef909f8
Some checks failed
Test macOS Build Action / test-macos-build (push) Failing after 28m28s
fix(workflows): update macOS build workflow to enable push triggers and refine local signing process
2025-04-14 16:04:47 +02:00

388 lines
16 KiB
YAML

name: Test Local Signing
on:
workflow_dispatch: # Manual trigger
# push:
# branches: [ozgur/build]
jobs:
test-local-signing:
runs-on: macos
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Create Test Entitlements
run: |
echo "📝 Creating entitlements file..."
cat > LuckyWorld.entitlements << EOF
<?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.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>
EOF
echo "✅ Created entitlements file"
cat LuckyWorld.entitlements
shell: bash
- name: Create Test App Bundle
run: |
echo "📦 Creating test app bundle..."
# Create test app bundle structure
TEST_APP_DIR="TestApp.app"
mkdir -p "$TEST_APP_DIR/Contents/MacOS"
# Create a simple test executable
echo '#!/bin/bash
echo "Hello from TestApp!"' > "$TEST_APP_DIR/Contents/MacOS/TestApp"
chmod +x "$TEST_APP_DIR/Contents/MacOS/TestApp"
# Create Info.plist
cat > "$TEST_APP_DIR/Contents/Info.plist" << EOF
<?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>CFBundleExecutable</key>
<string>TestApp</string>
<key>CFBundleIdentifier</key>
<string>com.luckyrobots.luckyworld.testapp</string>
<key>CFBundleName</key>
<string>TestApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.10</string>
</dict>
</plist>
EOF
echo "✅ Created test app bundle"
# Verify app bundle exists
if [ ! -d "$TEST_APP_DIR" ]; then
echo "❌ Error: App bundle not found at $TEST_APP_DIR"
exit 1
fi
echo "🔍 App bundle contents:"
ls -la "$TEST_APP_DIR"
# Store app path as environment variable
echo "APP_PATH=$(pwd)/TestApp.app" >> "$GITHUB_ENV"
shell: bash
- name: Setup Certificate
env:
CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE }}
CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
echo "🔐 Setting up certificate..."
# Create a temporary directory for certificates
CERT_DIR="$HOME/certificates"
mkdir -p "$CERT_DIR"
# Decode the certificate to a p12 file
echo "$CERTIFICATE_BASE64" | base64 --decode > "$CERT_DIR/certificate.p12"
# Check certificate format and details
echo "📑 Certificate format check:"
file "$CERT_DIR/certificate.p12"
# Try to get certificate info with openssl
echo "📑 Certificate info with OpenSSL:"
openssl pkcs12 -info -in "$CERT_DIR/certificate.p12" -nokeys -passin pass:"$CERTIFICATE_PASSWORD" || echo "Failed to read certificate with OpenSSL"
# Create keychain
KEYCHAIN_PATH="$CERT_DIR/app-signing.keychain-db"
KEYCHAIN_PASSWORD="temppassword123"
# Delete existing keychain if it exists
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
# Create new keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -t 3600 -u -l "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Add to search list and make default
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
security default-keychain -s "$KEYCHAIN_PATH"
# Try multiple import approaches
echo "🔑 Importing developer certificate - attempt 1 (standard)..."
security import "$CERT_DIR/certificate.p12" -k "$KEYCHAIN_PATH" -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign
echo "🔑 Importing developer certificate - attempt 2 (with flags)..."
security import "$CERT_DIR/certificate.p12" -k "$KEYCHAIN_PATH" -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign -x -A
echo "🔑 Importing developer certificate - attempt 3 (with format)..."
security import "$CERT_DIR/certificate.p12" -k "$KEYCHAIN_PATH" -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign -f pkcs12
# Set partition list for codesign to access keychain
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Check all certificates in keychain
echo "🔍 Listing all certificates in keychain..."
security find-certificate -a "$KEYCHAIN_PATH"
# Verify certificate
echo "🔍 Verifying code signing identities..."
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
# Alternative check for identities
echo "🔍 Listing identities with code signing usage..."
security find-certificate -a -c "Developer ID Application" -p "$KEYCHAIN_PATH" | grep -q "Code Signing" && echo "✅ Certificate has code signing usage" || echo "❌ Certificate does NOT have code signing usage"
# Try to use the System keychain as a fallback
echo "🔍 Checking system keychain for code signing identities..."
SYSTEM_IDENTITIES=$(security find-identity -v -p codesigning)
echo "$SYSTEM_IDENTITIES"
if echo "$SYSTEM_IDENTITIES" | grep -q "Developer ID Application"; then
echo "✅ Found Developer ID Application certificate in system keychain"
echo "USE_SYSTEM_CERT=true" >> "$GITHUB_ENV"
else
echo "❌ No Developer ID Application certificate found in system keychain"
echo "USE_SYSTEM_CERT=false" >> "$GITHUB_ENV"
fi
# Store keychain variables for later steps
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> "$GITHUB_ENV"
echo "APPLE_TEAM_ID=$APPLE_TEAM_ID" >> "$GITHUB_ENV"
# Debug: keep p12 file for inspection
echo "💾 Keeping certificate.p12 for debugging"
shell: bash
- name: Debug Certificate Content
if: always()
env:
CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
run: |
echo "🔎 Debugging certificate content..."
CERT_DIR="$HOME/certificates"
# Check if p12 file exists
if [ ! -f "$CERT_DIR/certificate.p12" ]; then
echo "❌ Certificate file not found"
exit 0
fi
# Try with OpenSSL to extract certificate info
echo "Attempting to extract certificate info..."
openssl pkcs12 -in "$CERT_DIR/certificate.p12" -info -nokeys -passin pass:"$CERTIFICATE_PASSWORD" > cert_info.txt || echo "Failed to extract info"
# Check certificate contents
echo "Certificate subject information:"
grep "subject" cert_info.txt || echo "No subject information found"
echo "Certificate issuer information:"
grep "issuer" cert_info.txt || echo "No issuer information found"
# Check if it's a Developer ID certificate
if grep -q "Developer ID" cert_info.txt; then
echo "✅ This appears to be a Developer ID certificate"
else
echo "❌ This does NOT appear to be a Developer ID certificate"
fi
# Check if it has a private key
echo "Checking for private key..."
if openssl pkcs12 -in "$CERT_DIR/certificate.p12" -nocerts -passin pass:"$CERTIFICATE_PASSWORD" -passout pass:temp 2>/dev/null; then
echo "✅ Certificate contains a private key"
else
echo "❌ Certificate does NOT contain a private key or wrong password"
fi
shell: bash
- name: Sign with Developer ID
run: |
echo "🔏 Signing app with Developer ID certificate..."
# Decide which keychain to use
if [ "${USE_SYSTEM_CERT:-false}" = "true" ]; then
echo "Using system keychain identity"
# Get certificate hash instead of name to avoid ambiguity
IDENTITY_HASH=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -1 | awk '{print $2}')
echo "Using certificate hash: $IDENTITY_HASH"
else
# Make sure keychain is unlocked
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "Using custom keychain identity"
# Get certificate hash instead of name to avoid ambiguity
IDENTITY_HASH=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" | grep "Developer ID Application" | head -1 | awk '{print $2}')
echo "Using certificate hash: $IDENTITY_HASH"
fi
if [ -z "$IDENTITY_HASH" ]; then
echo "❌ No valid Developer ID Application certificate found"
echo "Falling back to ad-hoc signing for testing..."
# Use ad-hoc identity as fallback
codesign --force --deep --verbose --options runtime --entitlements LuckyWorld.entitlements --sign - --timestamp "$APP_PATH"
echo "SIGNED=adhoc" >> "$GITHUB_ENV"
else
echo "Signing app bundle with Developer ID hash: $IDENTITY_HASH"
# Sign the app bundle using the hash
codesign --force --deep --verbose --options runtime --entitlements LuckyWorld.entitlements --sign "$IDENTITY_HASH" --timestamp "$APP_PATH"
echo "SIGNED=identity" >> "$GITHUB_ENV"
fi
# Verify signing
echo "🔍 Verifying signature..."
codesign -vvv --deep --strict "$APP_PATH"
# Check entitlements
echo "🔍 Checking entitlements..."
codesign -d --entitlements - "$APP_PATH"
shell: bash
- name: Notarize App
if: success()
env:
APPLE_ID: ${{ secrets.NOTARY_USER }}
APP_PASSWORD: ${{ secrets.NOTARY_PASSWORD }}
API_KEY_ID: ${{ secrets.NOTARY_API_KEY_ID }}
API_ISSUER_ID: ${{ secrets.NOTARY_API_KEY_ISSUER_ID }}
API_KEY_PATH: ${{ secrets.NOTARY_API_KEY_PATH }}
run: |
echo "📤 Notarizing app..."
# Check if we have API key credentials
if [ -n "$API_KEY_ID" ] && [ -n "$API_ISSUER_ID" ] && [ -n "$API_KEY_PATH" ]; then
echo "Using App Store Connect API key for notarization..."
# Create directory for API key if API_KEY_PATH contains content
mkdir -p ~/private_keys
# Check if API_KEY_PATH is a path or content
if [[ "$API_KEY_PATH" == /* ]] && [ -f "$API_KEY_PATH" ]; then
# It's a path to a file
echo "Using API key from path: $API_KEY_PATH"
cp "$API_KEY_PATH" ~/private_keys/AuthKey_${API_KEY_ID}.p8
else
# It contains the key content
echo "Using API key from content"
echo "$API_KEY_PATH" > ~/private_keys/AuthKey_${API_KEY_ID}.p8
fi
# Create zip for notarization
ZIP_PATH="TestApp-notarize.zip"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
echo "Submitting for notarization with API key..."
xcrun notarytool submit "$ZIP_PATH" \
--key ~/private_keys/AuthKey_${API_KEY_ID}.p8 \
--key-id "$API_KEY_ID" \
--issuer "$API_ISSUER_ID" \
--wait
# Staple the notarization ticket
echo "Stapling notarization ticket..."
xcrun stapler staple "$APP_PATH"
# Verify notarization
echo "🔍 Verifying notarization..."
spctl --assess --verbose --type exec "$APP_PATH"
echo "NOTARIZED=true" >> "$GITHUB_ENV"
# Clean up
rm -rf ~/private_keys
# Fall back to App-specific password if API key not available
elif [ -n "$APPLE_ID" ] && [ -n "$APP_PASSWORD" ] && [ -n "$APPLE_TEAM_ID" ]; then
echo "Using App-specific password for notarization..."
# Create zip for notarization
ZIP_PATH="TestApp-notarize.zip"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
echo "Submitting for notarization..."
xcrun notarytool submit "$ZIP_PATH" \
--apple-id "$APPLE_ID" \
--password "$APP_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait
# Staple the notarization ticket
echo "Stapling notarization ticket..."
xcrun stapler staple "$APP_PATH"
# Verify notarization
echo "🔍 Verifying notarization..."
spctl --assess --verbose --type exec "$APP_PATH"
echo "NOTARIZED=true" >> "$GITHUB_ENV"
else
echo "⚠️ Missing notarization credentials. Skipping notarization."
echo "For App Store Connect API key method, set these secrets:"
echo " - NOTARY_API_KEY_ID: Your API key ID"
echo " - NOTARY_API_KEY_ISSUER_ID: Your API issuer ID"
echo " - NOTARY_API_KEY_PATH: Path to or content of your p8 file"
echo ""
echo "For App-specific password method, set these secrets:"
echo " - NOTARY_USER: Your Apple ID (email)"
echo " - NOTARY_PASSWORD: Your app-specific password"
echo " - APPLE_TEAM_ID: Your Apple Developer team ID"
echo "NOTARIZED=false" >> "$GITHUB_ENV"
exit 0
fi
shell: bash
- name: Package Signed App
run: |
echo "📦 Packaging signed app..."
if [ "${NOTARIZED:-false}" == "true" ]; then
ZIP_FILE="TestApp-Signed-Notarized.zip"
echo "Creating distribution package with notarized app..."
else
ZIP_FILE="TestApp-Signed.zip"
echo "Creating distribution package with signed app..."
fi
# Create zip package
ditto -c -k --keepParent "$APP_PATH" "$ZIP_FILE"
echo "✅ Created package: $ZIP_FILE"
shell: bash
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: LuckyWorld-Signed-App
path: TestApp-*.zip
retention-days: 7
- name: Cleanup
if: always()
run: |
echo "🧹 Cleaning up..."
rm -rf TestApp.app TestApp-*.zip || true
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
echo "✅ Cleanup complete"
shell: bash