WIP: feat(workflows): add new build workflows for Windows, Linux, and macOS, and remove obsolete build scripts #17

Draft
m wants to merge 109 commits from ozgur/build into main
4 changed files with 215 additions and 36 deletions
Showing only changes of commit f28c4a21b5 - Show all commits

View File

@ -177,7 +177,61 @@ runs:
else
echo "Signing app bundle with Developer ID hash: $IDENTITY_HASH"
# Sign the app bundle using the hash
# Enhanced deep recursive signing for all binaries
echo "🔍 Performing deep recursive signing of all components..."
# First, find all .dylib files and sign them individually
echo "Signing all dynamic libraries (.dylib files)..."
find "${{ inputs.app-path }}" -name "*.dylib" | while read -r dylib; do
echo "Signing: $dylib"
codesign --force --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$dylib" || echo "⚠️ Failed to sign: $dylib"
done
# Sign all .so files
echo "Signing all shared objects (.so files)..."
find "${{ inputs.app-path }}" -name "*.so" | while read -r so; do
echo "Signing: $so"
codesign --force --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$so" || echo "⚠️ Failed to sign: $so"
done
# Sign all executable files (files with execute permission)
echo "Signing all executable files..."
find "${{ inputs.app-path }}" -type f -perm +111 -not -path "*.framework/*" -not -name "*.dylib" -not -name "*.so" | while read -r exe; do
echo "Signing executable: $exe"
codesign --force --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$exe" || echo "⚠️ Failed to sign: $exe"
done
# Sign all frameworks
echo "Signing frameworks..."
find "${{ inputs.app-path }}" -path "*.framework" -type d | while read -r framework; do
echo "Signing framework: $framework"
codesign --force --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$framework" || echo "⚠️ Failed to sign: $framework"
done
# Special handling for CrashReportClient.app
CRASH_REPORTER=$(find "${{ inputs.app-path }}" -path "*CrashReportClient.app" -type d | head -1)
if [ -n "$CRASH_REPORTER" ]; then
echo "🔍 Special handling for CrashReportClient.app: $CRASH_REPORTER"
# Sign CrashReportClient.app specifically with focus on hardened runtime
find "$CRASH_REPORTER" -type f -perm +111 | while read -r crash_bin; do
echo "Signing CrashReportClient binary: $crash_bin"
codesign --force --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$crash_bin" || echo "⚠️ Failed to sign: $crash_bin"
done
echo "Signing the CrashReportClient.app bundle itself..."
codesign --force --deep --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$CRASH_REPORTER" || echo "⚠️ Failed to sign CrashReportClient.app"
fi
# Sign any other nested app bundles
find "${{ inputs.app-path }}" -path "*.app" -type d | grep -v CrashReportClient | while read -r nested_app; do
if [ "$nested_app" != "${{ inputs.app-path }}" ]; then
echo "Signing nested app: $nested_app"
codesign --force --deep --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "$nested_app" || echo "⚠️ Failed to sign: $nested_app"
fi
done
# Final signing of the main bundle
echo "🔐 Performing final signing of the main app bundle..."
codesign --force --deep --verbose --options runtime --entitlements "${{ inputs.entitlements-file }}" --sign "$IDENTITY_HASH" --timestamp "${{ inputs.app-path }}"
echo "::set-output name=signed::identity"
fi
@ -189,6 +243,16 @@ runs:
# Check entitlements
echo "🔍 Checking entitlements..."
codesign -d --entitlements - "${{ inputs.app-path }}"
# Verify CrashReportClient
CRASH_REPORTER=$(find "${{ inputs.app-path }}" -path "*CrashReportClient.app" -type d | head -1)
if [ -n "$CRASH_REPORTER" ]; then
echo "🔍 Verifying CrashReportClient signature..."
codesign -vvv --deep --strict "$CRASH_REPORTER" || echo "⚠️ CrashReportClient may have verification issues"
echo "CrashReportClient entitlements:"
codesign -d --entitlements - "$CRASH_REPORTER" || echo "⚠️ Could not display CrashReportClient entitlements"
fi
- name: Notarize App
id: notarize

View File

@ -30,6 +30,29 @@ jobs:
echo "Environment setup complete"
shell: bash
# Set correct bundle identifier before build
- name: Set bundle identifier
run: |
# Set the correct bundle identifier in DefaultGame.ini if it exists
CONFIG_FILE="Config/DefaultGame.ini"
if [ -f "$CONFIG_FILE" ]; then
# Check if section exists or add it
if grep -q "\[/Script/MacTargetPlatform\.MacTargetSettings\]" "$CONFIG_FILE"; then
# Section exists, update the setting
sed -i '' 's/BundleIdentifier=.*/BundleIdentifier=com.luckyrobots.luckyworld/g' "$CONFIG_FILE"
else
# Section doesn't exist, add it
echo "" >> "$CONFIG_FILE"
echo "[/Script/MacTargetPlatform.MacTargetSettings]" >> "$CONFIG_FILE"
echo "BundleIdentifier=com.luckyrobots.luckyworld" >> "$CONFIG_FILE"
fi
echo "Updated bundle ID in project config"
fi
# Set the constant bundle ID for the workflow
echo "BUNDLE_ID=com.luckyrobots.luckyworld" >> "$GITHUB_ENV"
shell: bash
# Build for macOS - use your own build script or create a test app if needed
- name: Build for macOS
run: |
@ -86,14 +109,65 @@ jobs:
# Export APP_PATH for next steps to use
echo "APP_PATH=$MAIN_APP_PATH" >> "$GITHUB_ENV"
# Extract bundle ID from Info.plist
# Fix bundle ID in Info.plist before signing
if [ -f "$MAIN_APP_PATH/Contents/Info.plist" ]; then
BUNDLE_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$MAIN_APP_PATH/Contents/Info.plist")
echo "Detected bundle ID from app: $BUNDLE_ID"
echo "BUNDLE_ID=$BUNDLE_ID" >> "$GITHUB_ENV"
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 "WARNING: Could not find Info.plist in app bundle. Using default bundle ID."
echo "BUNDLE_ID=com.YourCompany.LuckyWorld" >> "$GITHUB_ENV"
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)
if [ -n "$NESTED_APPS" ]; then
echo "Found nested app bundles, fixing 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"
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"
fi
done
fi
shell: bash
# Fix common issues that may cause notarization failure
- name: Fix common issues for notarization
run: |
echo "🛠️ Fixing common issues that may cause notarization failure..."
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
# 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
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"
echo "Setting CrashReportClient bundle ID to $CRASH_BUNDLE_ID"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $CRASH_BUNDLE_ID" "$CRASH_REPORTER/Contents/Info.plist"
fi
fi
shell: bash
@ -112,7 +186,7 @@ jobs:
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: 'true'
fallback-to-adhoc: 'false'
# Upload signed app if available
- name: Upload Signed App

View File

@ -14,5 +14,13 @@
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@ -13,6 +13,22 @@ PROJECT_ROOT="$(pwd)"
PROJECT_FILE="$PROJECT_ROOT/LuckyWorld.uproject"
ARCHIVE_DIR="$PROJECT_ROOT/Builds"
# Check for Developer ID certificate
CERTIFICATE_NAME=""
if [ -z "$CERTIFICATE_NAME" ]; then
# Try to find a Developer ID Application certificate
CERTIFICATE_NAME=$(security find-identity -v -p codesigning | grep "Developer ID Application" | head -1 | sed -E 's/.*"(Developer ID Application.*)"$/\1/')
if [ -z "$CERTIFICATE_NAME" ]; then
echo "⚠️ No Developer ID Application certificate found. Please specify a valid certificate name."
echo "Available certificates:"
security find-identity -v -p codesigning
exit 1
else
echo "🔑 Found Developer ID certificate: $CERTIFICATE_NAME"
fi
fi
# Check for entitlements file
if [ -f "$PROJECT_ROOT/LuckyWorld.entitlements" ]; then
ENTITLEMENTS_FILE="$PROJECT_ROOT/LuckyWorld.entitlements"
@ -28,6 +44,7 @@ echo "Project root: $PROJECT_ROOT"
echo "Project file: $PROJECT_FILE"
echo "Archive directory: $ARCHIVE_DIR"
echo "Entitlements file: $ENTITLEMENTS_FILE"
echo "Signing with certificate: $CERTIFICATE_NAME"
# Clean up previous build artifacts
rm -rf DerivedDataCache Intermediate Binaries Saved
@ -97,17 +114,17 @@ if [ -n "$APP_PATH" ]; then
find "$APP_PATH" -name "*PhysX*" -o -name "*APEX*"
fi
# Bundle ID'yi proje ayarlarında güncelle
# Update bundle ID in project settings
echo ""
echo "🔧 Updating bundle ID in UE config..."
CONFIG_FILE="$PROJECT_ROOT/Config/DefaultGame.ini"
if [ -f "$CONFIG_FILE" ]; then
# Mevcut bölümü kontrol et veya ekle
# Check if section exists or add it
if grep -q "\[/Script/MacTargetPlatform\.MacTargetSettings\]" "$CONFIG_FILE"; then
# Bölüm var, ayarı güncelleyebiliriz
# Section exists, update the setting
sed -i '' 's/BundleIdentifier=.*/BundleIdentifier=com.luckyrobots.luckyworld/g' "$CONFIG_FILE"
else
# Bölüm yok, eklememiz gerekiyor
# Section doesn't exist, add it
echo "" >> "$CONFIG_FILE"
echo "[/Script/MacTargetPlatform.MacTargetSettings]" >> "$CONFIG_FILE"
echo "BundleIdentifier=com.luckyrobots.luckyworld" >> "$CONFIG_FILE"
@ -115,7 +132,7 @@ if [ -f "$CONFIG_FILE" ]; then
echo "Updated bundle ID in project config"
fi
# Build sonrası işlemler - bundle ID ayarlama
# Post-build process - set bundle ID
echo ""
echo "🔧 Performing post-build fix for bundle ID..."
if [ -n "$APP_PATH" ]; then
@ -129,16 +146,17 @@ if [ -n "$APP_PATH" ]; then
fi
fi
# Recursive imzalama fonksiyonu - tüm binary dosyaları imzalar
# Recursive signing function - signs all binary files
function sign_recursively() {
local app_path="$1"
local entitlements_file="$2"
local certificate="$3"
local counter=0
local total=0
local failed=0
# Önce toplam dosya sayısını hesapla
# Tüm binary dosyaları bul (executable, dylib, so, çerçeveler)
# First calculate total file count
# Find all binary files (executables, dylibs, .so files, frameworks)
echo "Scanning for binary files..."
# Executable binary files (libraries, executables)
@ -147,12 +165,12 @@ function sign_recursively() {
echo "Found $total binary files to sign"
# Helper binary dosyaları imzala (tercih sırasına göre)
# Sign helper binary files (in order of preference)
echo "Signing all binary files (libraries and executables)..."
echo "$binaries" | while read -r binary; do
counter=$((counter + 1))
# Her 20 dosyada bir ilerleme göster
# Show progress every 20 files
if [ $((counter % 20)) -eq 0 ] || [ $counter -eq 1 ] || [ $counter -eq $total ]; then
echo "Progress: $counter/$total - Signing: $binary"
fi
@ -162,10 +180,10 @@ function sign_recursively() {
continue
fi
# Dosya türünü kontrol et
# Check file type
file_info=$(file "$binary")
# Sadece Mach-O dosyalarını imzala
# Only sign Mach-O files
if ! echo "$file_info" | grep -q "Mach-O"; then
continue
fi
@ -174,18 +192,18 @@ function sign_recursively() {
echo "🛠️ Special handling for CrashReportClient: $binary"
fi
# Timestamp ve runtime options ile imzala
codesign --force --options runtime --deep --sign - --timestamp --entitlements "$entitlements_file" "$binary" 2>&1 || {
# Sign with timestamp and runtime options
codesign --force --options runtime --deep --sign "$certificate" --timestamp --entitlements "$entitlements_file" "$binary" 2>&1 || {
echo "⚠️ Failed to sign: $binary"
failed=$((failed + 1))
}
done
# Başvuru için ENTITLEMENTS içeriğini göster
# Show ENTITLEMENTS content for reference
echo "Using entitlements file for signatures:"
cat "$entitlements_file"
# Tüm nested app'leri bul ve imzala
# Find all nested apps and sign them
nested_apps=$(find "$app_path" -name "*.app" -type d)
if [ -n "$nested_apps" ]; then
@ -194,14 +212,14 @@ function sign_recursively() {
if [ "$nested_app" != "$app_path" ]; then
echo "Signing nested app: $nested_app"
# İmzalamadan önce Info.plist varsa Bundle ID ayarla
# Set Bundle ID in Info.plist if it exists before signing
nested_info="$nested_app/Contents/Info.plist"
if [ -f "$nested_info" ]; then
echo "Setting bundle identifier for nested app"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.luckyrobots.luckyworld.nested" "$nested_info" 2>/dev/null || true
fi
codesign --force --options runtime --deep --sign - --timestamp --entitlements "$entitlements_file" "$nested_app" 2>&1 || {
codesign --force --options runtime --deep --sign "$certificate" --timestamp --entitlements "$entitlements_file" "$nested_app" 2>&1 || {
echo "⚠️ Failed to sign nested app: $nested_app"
failed=$((failed + 1))
}
@ -209,24 +227,24 @@ function sign_recursively() {
done
fi
# Asıl uygulamayı imzala
# Sign the main application
echo "Signing main application: $app_path"
codesign --force --options runtime --deep --sign - --timestamp --entitlements "$entitlements_file" "$app_path" 2>&1 || {
codesign --force --options runtime --deep --sign "$certificate" --timestamp --entitlements "$entitlements_file" "$app_path" 2>&1 || {
echo "⚠️ Failed to sign main app: $app_path"
failed=$((failed + 1))
}
echo "✅ Signing completed: $counter files processed, $failed failures"
# İmzalama durumunu kontrol et
# Check signing status
echo "Verifying signatures..."
codesign -vvv --deep --strict "$app_path"
# Hardened Runtime ve diğer güvenlik ayarları kontrol et
# Check Hardened Runtime and other security settings
echo "Checking security settings (Hardened Runtime, etc.):"
codesign -d --entitlements - "$app_path" | grep -i "runtime\|hardened\|security"
# Spesifik olarak CrashReportClient'i kontrol et (sorunlu dosya)
# Check CrashReportClient specifically (problematic file)
crash_reporter=$(find "$app_path" -path "*CrashReportClient.app/Contents/MacOS/CrashReportClient" -type f | head -1)
if [ -n "$crash_reporter" ]; then
echo "Checking CrashReportClient specifically:"
@ -234,18 +252,33 @@ function sign_recursively() {
fi
}
# Kütüphaneleri kontrol et ve gerekirse post-processing yap
# Check libraries and perform post-processing if needed
echo ""
echo "🔍 Performing comprehensive signing and hardening of all binaries..."
if [ -n "$APP_PATH" ] && [ -n "$ENTITLEMENTS_FILE" ]; then
# Recursive olarak tüm binary dosyaları imzala
sign_recursively "$APP_PATH" "$ENTITLEMENTS_FILE"
# Sign all binary files recursively
sign_recursively "$APP_PATH" "$ENTITLEMENTS_FILE" "$CERTIFICATE_NAME"
# Son olarak ana uygulamayı tekrar imzala
# Final signing of the main app bundle
echo "Final signing of main app bundle"
codesign --force --options runtime --deep --sign - --timestamp --entitlements "$ENTITLEMENTS_FILE" "$APP_PATH"
codesign --force --options runtime --deep --sign "$CERTIFICATE_NAME" --timestamp --entitlements "$ENTITLEMENTS_FILE" "$APP_PATH"
echo "✅ All binaries signed successfully with Hardened Runtime enabled"
# Prepare app for notarization
echo ""
echo "🔐 Preparing for notarization..."
# Create a ZIP archive for notarization
ZIP_PATH="$ARCHIVE_DIR/LuckyWorld.zip"
echo "Creating ZIP archive for notarization: $ZIP_PATH"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
echo "✅ ZIP archive created for notarization at: $ZIP_PATH"
echo ""
echo "To notarize the app, run the following command:"
echo "xcrun notarytool submit \"$ZIP_PATH\" --apple-id \"YOUR_APPLE_ID\" --password \"APP_SPECIFIC_PASSWORD\" --team-id \"YOUR_TEAM_ID\" --wait"
echo ""
else
echo "❌ App path or entitlements file not found, cannot perform comprehensive signing"
echo "App path: $APP_PATH"