LuckyWorld/.gitea/workflows/test-macos-build.yml

271 lines
11 KiB
YAML

name: Test macOS Build Action
on:
workflow_dispatch: # Manual trigger only for testing
# push:
# branches: [ozgur/build]
jobs:
test-macos-build:
runs-on: macos
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
lfs: true
fetch-depth: 0
# Setup environment for build
- name: Setup environment
run: |
# Get the working directory path for absolute paths
WORKSPACE_DIR="$(pwd)"
echo "WORKSPACE_DIR=$WORKSPACE_DIR" >> "$GITHUB_ENV"
echo "ENTITLEMENTS_FILE=LuckyWorld.entitlements" >> "$GITHUB_ENV"
# Set CI environment variable to true for build script
echo "CI=true" >> "$GITHUB_ENV"
# Create directories for builds
mkdir -p Builds/Mac
mkdir -p PackagedReleases
mkdir -p ArchivedApps
echo "Environment setup complete"
shell: bash
# Build for macOS - use your own build script
- name: Build for macOS
run: |
if [ -f "./scripts/mac_build.sh" ]; then
chmod +x ./scripts/mac_build.sh
# Set CI environment variable explicitly before running
export CI=true
./scripts/mac_build.sh
# Check if the build succeeded by looking for the app
APP_PATHS=$(find ./Builds -type d -name "*.app" 2>/dev/null || echo "")
if [ -z "$APP_PATHS" ]; then
APP_PATHS=$(find ./Saved/StagedBuilds -type d -name "*.app" 2>/dev/null || echo "")
fi
if [ -z "$APP_PATHS" ]; then
echo "❌ ERROR: Build command appeared to succeed but no app bundle was found!"
echo "This usually means the build failed but didn't properly return an error code."
exit 1
fi
else
echo "ERROR: Build script not found at ./scripts/mac_build.sh"
exit 1
fi
shell: bash
# Find the app bundle
- name: Find app bundle
run: |
# Add error handling
set +e # Don't exit immediately on error for this block
echo "Build status check..."
if [ ! -d "./Builds" ] && [ ! -d "./Saved/StagedBuilds" ]; then
echo "❌ ERROR: Build directories do not exist. Build likely failed."
exit 1
fi
# First check Saved/StagedBuilds directory - where Unreal often places built apps
echo "Checking Saved/StagedBuilds directory..."
APP_PATHS=$(find ./Saved/StagedBuilds -type d -name "*.app" 2>/dev/null || echo "")
# If not found, check Builds directory
if [ -z "$APP_PATHS" ]; then
echo "No app found in Saved/StagedBuilds, checking Builds directory..."
APP_PATHS=$(find ./Builds -type d -name "*.app" 2>/dev/null || echo "")
fi
# If still not found, check the whole workspace
if [ -z "$APP_PATHS" ]; then
echo "No app found in Builds, checking entire workspace..."
APP_PATHS=$(find . -type d -name "*.app" -not -path "*/\.*" 2>/dev/null || echo "")
fi
if [ -z "$APP_PATHS" ]; then
echo "❌ ERROR: Could not find any app bundles!"
echo "Listing all directories to help debug:"
find . -type d -maxdepth 3 | sort
exit 1
fi
echo "Found potential app bundles:"
echo "$APP_PATHS"
# Use the first app path found (preferably the main app, not a child app)
MAIN_APP_PATH=$(echo "$APP_PATHS" | grep -v "CrashReportClient" | head -1 || echo "$APP_PATHS" | head -1)
echo "Using app bundle: $MAIN_APP_PATH"
echo "APP_PATH=$MAIN_APP_PATH" >> "$GITHUB_ENV"
# Make sure app exists - using local variable
if [ ! -d "$MAIN_APP_PATH" ]; then
echo "❌ ERROR: App bundle not found at $MAIN_APP_PATH!"
exit 1
fi
# Export APP_PATH for next steps to use
echo "APP_PATH=$MAIN_APP_PATH" >> "$GITHUB_ENV"
# Get bundle ID from Info.plist for reference (not modifying)
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: $BUNDLE_ID"
echo "BUNDLE_ID=$BUNDLE_ID" >> "$GITHUB_ENV"
fi
shell: bash
# Basic pre-notarization checks
- name: Check for notarization issues
run: |
echo "🔍 Checking app for potential notarization issues..."
APP_PATH="${{ env.APP_PATH }}"
# 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 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 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
# Make install scripts executable
chmod +x ./scripts/install_luckyworld.sh
chmod +x ./scripts/create_dmg.sh
shell: bash
# 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:
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 only the DMG file from the macos-notarize action
- name: Upload Standard 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
# Install create-dmg tool
- name: Install create-dmg tool
run: |
if ! command -v brew &> /dev/null; then
echo "Homebrew is not installed. Installing now..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [[ -d "/opt/homebrew/bin/" ]]; then
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
if [[ -d "/usr/local/bin/" ]]; then
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/usr/local/bin/brew shellenv)"
fi
echo "Homebrew installed successfully!"
fi
brew install create-dmg
shell: bash
- name: Setup CI Variables
run: echo "CI=true" >> $GITHUB_ENV
shell: bash
# Create custom DMG with installer script
- name: Create Custom DMG with Installer
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none'
run: |
echo "Creating custom DMG with installer script..."
APP_PATH="${{ env.APP_PATH }}"
mkdir -p "./PackagedReleases/Install"
rm -rf "./PackagedReleases/Install/*" 2>/dev/null || true
# Copy the app and installer to package directory
cp -R "$APP_PATH" "./PackagedReleases/Install/"
cp "./scripts/install_luckyworld.sh" "./PackagedReleases/Install/"
chmod +x "./PackagedReleases/Install/install_luckyworld.sh"
# Create a simple README
echo "Writing README file"
printf "LuckyWorld Installer\n===================\n\n1. Double-click install_luckyworld.sh to install\n2. Follow on-screen instructions\n\nFor help: https://luckyrobots.io\n" > "./PackagedReleases/Install/README.txt"
# Create DMG using direct hdiutil approach (native macOS command)
CUSTOM_DMG_PATH="./PackagedReleases/LuckyWorld-Installer.dmg"
rm -f "$CUSTOM_DMG_PATH" 2>/dev/null || true
hdiutil create -volname "LuckyWorld Installer" -srcfolder "./PackagedReleases/Install" -ov -format UDZO "$CUSTOM_DMG_PATH"
if [ $? -ne 0 ]; then
echo "❌ DMG creation failed! Creating a ZIP file as fallback..."
( cd "./PackagedReleases" && zip -r "LuckyWorld-Installer.zip" "Install" )
CUSTOM_DMG_PATH="./PackagedReleases/LuckyWorld-Installer.zip"
fi
if [ -f "$CUSTOM_DMG_PATH" ]; then
echo "✅ Package created successfully: $CUSTOM_DMG_PATH"
echo "Size: $(du -h "$CUSTOM_DMG_PATH" | cut -f1)"
echo "CUSTOM_DMG_PATH=$CUSTOM_DMG_PATH" >> $GITHUB_ENV
else
echo "❌ Failed to create installation package"
exit 1
fi
# Clean up temporary directory
rm -rf "./PackagedReleases/Install"
shell: bash
# Upload the custom DMG with installer script
- name: Upload Custom DMG with Installer
uses: actions/upload-artifact@v3
if: steps.sign-and-notarize.outputs.notarized == 'true' && steps.sign-and-notarize.outputs.signed != 'none' && env.CUSTOM_DMG_PATH != ''
with:
name: LuckyWorld-macOS-Installer-DMG
path: ${{ env.CUSTOM_DMG_PATH }}
retention-days: 30
# Report results
- name: Report Results
run: |
echo "🔐 App signing: ${{ steps.sign-and-notarize.outputs.signed }}"
echo "🔏 App notarization: ${{ steps.sign-and-notarize.outputs.notarized }}"
if [ "${{ steps.sign-and-notarize.outputs.signed }}" != "none" ]; then
echo "✅ Packaging completed successfully!"
echo "Final standard package: ${{ steps.sign-and-notarize.outputs.package-path }}"
if [ -n "$CUSTOM_DMG_PATH" ] && [ -f "$CUSTOM_DMG_PATH" ]; then
echo "Final installer package: $CUSTOM_DMG_PATH"
fi
else
echo "⚠️ App was not signed - check the logs for details"
fi
shell: bash