fix(actions): simplify macOS build workflow by removing redundant bundle ID checks and enhancing notarization issue verification
Some checks failed
Test macOS Build Action / test-macos-build (push) Failing after 15m9s

This commit is contained in:
Ozgur 2025-04-15 20:48:33 +02:00
parent 659b5de3ea
commit 619d4d8298
No known key found for this signature in database
GPG Key ID: 66CDF27505A35546
3 changed files with 47 additions and 320 deletions

View File

@ -29,48 +29,12 @@ jobs:
# Create directories for builds
mkdir -p Builds/Mac
mkdir -p PackagedReleases
mkdir -p ArchivedApps
echo "Environment setup complete"
shell: bash
# Verify bundle identifier is correctly set
- name: Verify bundle identifier
run: |
# Set the constant bundle ID for the workflow
echo "BUNDLE_ID=com.luckyrobots.luckyworld" >> "$GITHUB_ENV"
# Verify the bundle ID is correctly set in DefaultGame.ini
CONFIG_FILE="Config/DefaultGame.ini"
if [ -f "$CONFIG_FILE" ]; then
if grep -q "\[/Script/MacTargetPlatform\.MacTargetSettings\]" "$CONFIG_FILE" && grep -q "BundleIdentifier=com.luckyrobots.luckyworld" "$CONFIG_FILE"; then
echo "✅ Bundle ID correctly set in DefaultGame.ini"
else
echo "⚠️ Warning: Bundle ID may not be correctly set in DefaultGame.ini"
echo "Please make sure the following section exists:"
echo "[/Script/MacTargetPlatform.MacTargetSettings]"
echo "BundleIdentifier=com.luckyrobots.luckyworld"
fi
else
echo "⚠️ DefaultGame.ini not found!"
fi
shell: bash
# Check Unreal Engine Project settings
- name: Inspect Unreal Settings
run: |
# Check for any potential issues in UE project settings
if [ -f "Config/DefaultEngine.ini" ]; then
echo "Checking DefaultEngine.ini for settings that might affect bundle ID..."
grep -i "bundle\|identifier\|package" Config/DefaultEngine.ini || echo "No relevant settings found"
fi
if [ -f "Config/DefaultGame.ini" ]; then
echo "Checking DefaultGame.ini for settings that might affect bundle ID..."
grep -i "bundle\|identifier\|package" Config/DefaultGame.ini || echo "No relevant settings found"
fi
shell: bash
# Build for macOS - use your own build script or create a test app if needed
# Build for macOS - use your own build script
- name: Build for macOS
run: |
if [ -f "./scripts/mac_build.sh" ]; then
@ -105,27 +69,6 @@ jobs:
echo "Build status check..."
if [ ! -d "./Builds" ] && [ ! -d "./Saved/StagedBuilds" ]; then
echo "❌ ERROR: Build directories do not exist. Build likely failed."
echo "Checking build logs for common issues..."
# Check for the specific GlobalDefinitions error
if grep -q "GlobalDefinitions.*This is not allowed" "$GITHUB_WORKSPACE"/*.log 2>/dev/null || grep -q "BuildEnvironment\|bOverrideBuildEnvironment" "$GITHUB_WORKSPACE"/*.log 2>/dev/null; then
echo "🔍 Found issue with GlobalDefinitions in build target."
echo "⚠️ Fix required in LuckyWorld.Target.cs - need to add bOverrideBuildEnvironment = true;"
echo "Fix suggestion for LuckyWorld.Target.cs:"
echo "Add this line in the constructor:"
echo " bOverrideBuildEnvironment = true;"
echo ""
echo "Example:"
echo " public LuckyWorldTarget(TargetInfo Target) : base(Target)"
echo " {"
echo " Type = TargetType.Game;"
echo " DefaultBuildSettings = BuildSettingsVersion.V5;"
echo " bOverrideBuildEnvironment = true; // Add this line"
echo " "
echo " // Rest of your constructor..."
echo " }"
fi
exit 1
fi
@ -170,96 +113,35 @@ jobs:
# Export APP_PATH for next steps to use
echo "APP_PATH=$MAIN_APP_PATH" >> "$GITHUB_ENV"
# Note: While bundle ID should be set by Unreal Engine build system based on DefaultGame.ini
# and LuckyWorld.Build.cs settings, we still check and fix if needed as a safety measure,
# since UE builds can sometimes have issues with bundle ID propagation
echo "Checking bundle IDs (fallback fix in case UE didn't properly apply settings)..."
# Fix bundle ID in Info.plist before signing
# Get bundle ID from Info.plist for reference (not modifying)
if [ -f "$MAIN_APP_PATH/Contents/Info.plist" ]; then
echo "Checking current bundle identifier..."
CURRENT_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$MAIN_APP_PATH/Contents/Info.plist")
echo "Current bundle ID: $CURRENT_BUNDLE_ID"
if [ "$CURRENT_BUNDLE_ID" != "$BUNDLE_ID" ]; then
echo "Bundle ID mismatch - fixing it!"
echo "Setting bundle identifier to $BUNDLE_ID"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$MAIN_APP_PATH/Contents/Info.plist"
echo "Updated bundle ID in Info.plist: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$MAIN_APP_PATH/Contents/Info.plist")"
else
echo "✅ Bundle ID is already correct: $BUNDLE_ID"
fi
else
echo "WARNING: Could not find Info.plist in app bundle."
fi
# Find and repair nested app bundles as well (like CrashReportClient.app)
NESTED_APPS=$(find "$MAIN_APP_PATH" -name "*.app" -type d | grep -v "^$MAIN_APP_PATH$")
if [ -n "$NESTED_APPS" ]; then
echo "Found nested app bundles, checking their bundle IDs:"
echo "$NESTED_APPS" | while read -r NESTED_APP; do
if [ -f "$NESTED_APP/Contents/Info.plist" ]; then
NESTED_NAME=$(basename "$NESTED_APP" .app)
NESTED_BUNDLE_ID="$BUNDLE_ID.$NESTED_NAME"
CURRENT_NESTED_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")
if [ "$CURRENT_NESTED_ID" != "$NESTED_BUNDLE_ID" ]; then
echo "Setting nested bundle ID to $NESTED_BUNDLE_ID for $NESTED_APP"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $NESTED_BUNDLE_ID" "$NESTED_APP/Contents/Info.plist"
# Verify the change
UPDATED_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")
echo "Updated nested app bundle ID: $UPDATED_ID"
else
echo "✅ Nested app $NESTED_NAME already has correct bundle ID: $CURRENT_NESTED_ID"
fi
fi
done
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$MAIN_APP_PATH/Contents/Info.plist")
echo "Detected bundle ID: $BUNDLE_ID"
echo "BUNDLE_ID=$BUNDLE_ID" >> "$GITHUB_ENV"
fi
shell: bash
# Fix common issues that may cause notarization failure
- name: Fix common issues for notarization
# Basic pre-notarization checks
- name: Check for notarization issues
run: |
echo "🛠️ Fixing common issues that may cause notarization failure..."
echo "🔍 Checking app for potential notarization issues..."
APP_PATH="${{ env.APP_PATH }}"
# Remove get-task-allow entitlement from Info.plist files
echo "Checking for get-task-allow entitlement..."
find "$APP_PATH" -name "*.plist" -exec plutil -convert xml1 {} \; -exec grep -l "get-task-allow" {} \; | while read -r plist_file; do
echo "Removing get-task-allow from $plist_file"
/usr/libexec/PlistBuddy -c "Delete :com.apple.security.get-task-allow" "$plist_file" 2>/dev/null || true
done
# Verify code signature already exists (from Unreal build)
echo "Checking existing signature..."
codesign -vvv "$APP_PATH" || echo "⚠️ App may not be properly signed by Unreal Engine"
# Check for problematic libraries that cause issues
echo "Looking for problematic files..."
PROBLEM_FILES=$(find "$APP_PATH" -type f -name "*.dylib" | grep -i "boost\|tbb\|ogg\|vorbis\|onnx")
if [ -n "$PROBLEM_FILES" ]; then
echo "Found potentially problematic libraries. These will be carefully handled during signing:"
echo "$PROBLEM_FILES" | head -10
if [ $(echo "$PROBLEM_FILES" | wc -l) -gt 10 ]; then
echo "... and $(echo "$PROBLEM_FILES" | wc -l) more"
fi
# Check for any ad-hoc signatures that would cause issues
if codesign -dvv "$APP_PATH" 2>&1 | grep -q "adhoc"; then
echo "⚠️ Warning: Ad-hoc signature detected. This will be replaced with a proper signature."
fi
# Verify CrashReportClient specifically
CRASH_REPORTER=$(find "$APP_PATH" -path "*CrashReportClient.app*" -type d | head -1)
if [ -n "$CRASH_REPORTER" ]; then
echo "Found CrashReportClient at $CRASH_REPORTER"
if [ -f "$CRASH_REPORTER/Contents/Info.plist" ]; then
# Ensure it has the correct bundle ID format
CRASH_BUNDLE_ID="$BUNDLE_ID.CrashReportClient"
CURRENT_CRASH_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$CRASH_REPORTER/Contents/Info.plist")
if [ "$CURRENT_CRASH_ID" != "$CRASH_BUNDLE_ID" ]; then
echo "Setting CrashReportClient bundle ID to $CRASH_BUNDLE_ID"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $CRASH_BUNDLE_ID" "$CRASH_REPORTER/Contents/Info.plist"
echo "Updated CrashReportClient bundle ID: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$CRASH_REPORTER/Contents/Info.plist")"
else
echo "✅ CrashReportClient already has correct bundle ID: $CURRENT_CRASH_ID"
fi
fi
# Verify entitlements file exists
if [ ! -f "${{ env.ENTITLEMENTS_FILE }}" ]; then
echo "⚠️ Entitlements file not found. Will use default entitlements."
else
echo "Found entitlements file: ${{ env.ENTITLEMENTS_FILE }}"
fi
shell: bash
@ -280,69 +162,13 @@ jobs:
bundle-id: ${{ env.BUNDLE_ID }}
fallback-to-adhoc: 'false'
# Additional verification and stapling to ensure the app opens without warning
- name: Verify and Staple App
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none'
run: |
echo "🔒 Performing additional verification and stapling..."
APP_PATH="${{ env.APP_PATH }}"
# Make sure the app is properly stapled
echo "Stapling notarization ticket to the app..."
xcrun stapler staple "$APP_PATH"
# Verify the stapling
echo "Verifying stapling..."
xcrun stapler validate "$APP_PATH"
# Perform deep verification of code signing
echo "Verifying code signature (deep)..."
codesign -vvv --deep "$APP_PATH"
# Additional check for quarantine attributes
echo "Checking for quarantine attributes..."
if [ -n "$(xattr -l "$APP_PATH" | grep quarantine)" ]; then
echo "Removing quarantine attribute..."
xattr -d com.apple.quarantine "$APP_PATH"
else
echo "No quarantine attribute found, good!"
fi
echo "✅ Verification and stapling completed!"
# Export STAPLED_APP_PATH for later use
echo "STAPLED_APP_PATH=$APP_PATH" >> "$GITHUB_ENV"
shell: bash
# Create a DMG file (macOS disk image) for easy distribution
- name: Create DMG for Distribution
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none'
run: |
STAPLED_APP_PATH="${{ env.STAPLED_APP_PATH }}"
APP_NAME=$(basename "$STAPLED_APP_PATH" .app)
ARCHIVE_DIR="./ArchivedApps"
DMG_FILE="$ARCHIVE_DIR/$APP_NAME.dmg"
# Note: The actual DMG creation, signing, notarization and stapling
# are now handled by the macos-notarize action
# Just ensure we have the correct path for outputs
if [ -f "${{ steps.sign-and-notarize.outputs.package-path }}" ]; then
echo "Using DMG created by the macos-notarize action"
echo "DMG file location: ${{ steps.sign-and-notarize.outputs.package-path }}"
echo "STAPLED_APP_DMG=${{ steps.sign-and-notarize.outputs.package-path }}" >> "$GITHUB_ENV"
else
echo "⚠️ DMG not found from the macos-notarize action output"
fi
shell: bash
# 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.STAPLED_APP_PATH }}
path: ${{ env.APP_PATH }}
retention-days: 30
# Create a properly archived ZIP of the stapled app (preserves stapling)

View File

@ -361,3 +361,13 @@ EnableCodeCoverage=False
EnableCodeCoveragePath=(Path="")
ForwardShading=False
UseFastCopyToResolve=True
[/Script/MacTargetPlatform.XcodeProjectSettings]
bMacSignToRunLocally=False
CodeSigningPrefix=com.luckyrobots
ApplicationDisplayName=LuckyWorld
CodeSigningTeam=937UD94CX2
bUseAutomaticCodeSigning=False
ShippingSpecificMacEntitlements=(FilePath="../LuckyWorld.entitlements")
MacSigningIdentity=Developer ID Application

View File

@ -16,24 +16,26 @@ ARCHIVE_DIR="$PROJECT_ROOT/Builds"
# Check for entitlements file
if [ -f "$PROJECT_ROOT/LuckyWorld.entitlements" ]; then
ENTITLEMENTS_FILE="$PROJECT_ROOT/LuckyWorld.entitlements"
echo "✅ Using entitlements file: $ENTITLEMENTS_FILE"
else
echo "Warning: No entitlements file found. This might affect notarization."
echo "⚠️ Warning: No entitlements file found. This might affect notarization."
ENTITLEMENTS_FILE=""
fi
# For debugging: print paths and config
# Print paths and config for debugging
echo "Project root: $PROJECT_ROOT"
echo "Project file: $PROJECT_FILE"
echo "Archive directory: $ARCHIVE_DIR"
echo "Entitlements file: $ENTITLEMENTS_FILE"
# Clean up previous build artifacts
rm -rf DerivedDataCache Intermediate Binaries Saved
# Generate project files
echo "📝 Generating project files..."
"$UE_ROOT/Engine/Build/BatchFiles/Mac/GenerateProjectFiles.sh" -project="$PROJECT_FILE" -game -engine
# Run the build command
echo "🔨 Starting build process..."
"$UE_UAT" -ScriptsForProject="$PROJECT_FILE" Turnkey \
-command=VerifySdk \
-platform=Mac \
@ -61,20 +63,11 @@ rm -rf DerivedDataCache Intermediate Binaries Saved
-prereqs \
-archivedirectory="$ARCHIVE_DIR" \
-CrashReporter \
-clientconfig=Shipping \
# -nocompile \
# -nocompileuat \
# -nocompileeditor \
# -skipbuildeditor \
# enable these if you want to test build without pak and iostore (you're just testing the build)
# -skipiostore \
# -skippak \ (disable -pak and -iostore)
-clientconfig=Shipping
echo ""
echo "🦾 Build completed. Application path:"
echo "🔍 Looking for built application..."
APP_PATH=$(find "$ARCHIVE_DIR" -name "*.app" -type d | head -n 1)
echo "$APP_PATH"
# Check if the build actually succeeded by verifying the app exists
if [ -z "$APP_PATH" ] || [ ! -d "$APP_PATH" ]; then
@ -86,9 +79,12 @@ if [ -z "$APP_PATH" ] || [ ! -d "$APP_PATH" ]; then
exit 1
fi
echo "✅ Build completed successfully! Application path:"
echo "$APP_PATH"
if [ -n "$APP_PATH" ]; then
echo ""
echo "🔍 Binary files that will need signing:"
echo "🔍 Binary files summary:"
DYLIB_COUNT=$(find "$APP_PATH" -name "*.dylib" | wc -l)
SO_COUNT=$(find "$APP_PATH" -name "*.so" | wc -l)
FRAMEWORKS=$(find "$APP_PATH" -path "*.framework/*" -type f -perm +111 | wc -l)
@ -100,120 +96,15 @@ if [ -n "$APP_PATH" ]; then
echo "- $EXECUTABLES other executables"
echo "Total binary files: $((DYLIB_COUNT + SO_COUNT + FRAMEWORKS + EXECUTABLES))"
echo ""
echo "🔍 Checking for PhysX and other special libraries (often need special handling):"
find "$APP_PATH" -name "*PhysX*" -o -name "*APEX*"
fi
# Update bundle ID in project settings
echo ""
echo "🔧 Checking for bundle ID in UE config..."
CONFIG_FILE="$PROJECT_ROOT/Config/DefaultGame.ini"
if [ -f "$CONFIG_FILE" ]; then
if grep -q "\[/Script/MacTargetPlatform\.MacTargetSettings\]" "$CONFIG_FILE" && grep -q "BundleIdentifier=com.luckyrobots.luckyworld" "$CONFIG_FILE"; then
echo "Bundle ID already correctly set in project config ✅"
else
echo "⚠️ Warning: Bundle ID may not be correctly set in DefaultGame.ini"
echo "Please ensure [/Script/MacTargetPlatform.MacTargetSettings] section exists with BundleIdentifier=com.luckyrobots.luckyworld"
fi
else
echo "⚠️ Config file not found at $CONFIG_FILE"
fi
# Post-build process - set bundle ID
echo ""
echo "🔍 Checking bundle ID in built app..."
echo "Note: Bundle ID should be automatically set by Unreal Engine based on DefaultGame.ini and"
echo "LuckyWorld.Build.cs settings, but UE sometimes fails to apply it correctly."
echo "Therefore, we keep this check and fix as a safety measure."
if [ -n "$APP_PATH" ]; then
# Check bundle ID (for information only, no modifications)
INFO_PLIST="$APP_PATH/Contents/Info.plist"
if [ -f "$INFO_PLIST" ]; then
CURRENT_BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$INFO_PLIST")
echo "Current bundle ID: $CURRENT_BUNDLE_ID"
if [ "$CURRENT_BUNDLE_ID" != "com.luckyrobots.luckyworld" ]; then
echo "Bundle ID mismatch - fixing it!"
echo "Setting bundle identifier to com.luckyrobots.luckyworld"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.luckyrobots.luckyworld" "$INFO_PLIST"
echo "Updated bundle ID: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$INFO_PLIST")"
else
echo "✅ Bundle ID is already correct: com.luckyrobots.luckyworld"
fi
else
echo "⚠️ Info.plist not found at $INFO_PLIST"
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$INFO_PLIST")
echo ""
echo "📦 App Bundle ID: $BUNDLE_ID"
fi
fi
# If this is a manual build (not in CI), attempt to sign the app locally
if [ -z "$CI" ] && [ -n "$APP_PATH" ]; then
echo ""
echo "🔐 Attempting local code signing and stapling..."
# Check if we have a valid Apple Developer identity
IDENTITY=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -1 | sed -E 's/.*\) ([A-F0-9]+) "(.*)"/\2/')
if [ -n "$IDENTITY" ]; then
echo "Found signing identity: $IDENTITY"
# Sign the app
echo "Signing application..."
if [ -f "$PROJECT_ROOT/LuckyWorld.entitlements" ]; then
echo "Using entitlements file: $PROJECT_ROOT/LuckyWorld.entitlements"
codesign --force --options runtime --entitlements "$PROJECT_ROOT/LuckyWorld.entitlements" --sign "$IDENTITY" --deep "$APP_PATH"
else
codesign --force --options runtime --sign "$IDENTITY" --deep "$APP_PATH"
fi
# Verify signature
echo "Verifying signature..."
codesign -vvv --deep "$APP_PATH"
# Staple the app if notarization is successful
echo "Checking if notarization is needed..."
if xcrun altool --notarization-info $(uuidgen) -u "YOUR_APPLE_ID" 2>&1 | grep -q "success"; then
echo "App is notarized, stapling the ticket..."
xcrun stapler staple "$APP_PATH"
xcrun stapler validate "$APP_PATH"
# Remove quarantine attribute if present
if [ -n "$(xattr -l "$APP_PATH" | grep quarantine)" ]; then
echo "Removing quarantine attribute..."
xattr -d com.apple.quarantine "$APP_PATH"
fi
else
echo "App is not notarized yet. Upload to Apple's notary service for full verification."
fi
else
echo "⚠️ No Developer ID Application certificate found for signing."
echo "Run 'security find-identity -v -p codesigning' to view available certificates."
fi
else
echo "Skipping local signing (running in CI or app not found)"
fi
# Find and check nested app bundles (like CrashReportClient.app)
NESTED_APPS=$(find "$APP_PATH" -name "*.app" -type d | grep -v "^$APP_PATH$")
if [ -n "$NESTED_APPS" ]; then
echo "Checking nested app bundles:"
echo "$NESTED_APPS" | while read -r NESTED_APP; do
if [ -f "$NESTED_APP/Contents/Info.plist" ]; then
NESTED_NAME=$(basename "$NESTED_APP" .app)
NESTED_BUNDLE_ID="com.luckyrobots.luckyworld.$NESTED_NAME"
CURRENT_NESTED_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")
if [ "$CURRENT_NESTED_ID" != "$NESTED_BUNDLE_ID" ]; then
echo "Setting nested bundle ID to $NESTED_BUNDLE_ID for $NESTED_APP"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $NESTED_BUNDLE_ID" "$NESTED_APP/Contents/Info.plist"
echo "Updated nested app bundle ID: $(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$NESTED_APP/Contents/Info.plist")"
else
echo "Nested app bundle ID already correct: $CURRENT_NESTED_ID"
fi
fi
done
fi
echo ""
echo "✅ Build and post-processing completed!"
echo "✅ Build complete!"
echo "App location: $APP_PATH"