| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- name: Build Samples
- on:
- workflow_dispatch:
- push:
- branches: [ main, develop ]
- pull_request:
- branches: [ main, develop ]
- schedule:
- - cron: "0 3 * * 1" # Weekly (Mon) build to keep artifacts fresh
- permissions:
- contents: read
- env:
- DOTNET_NOLOGO: true
- CONFIGURATION: Release
- jobs:
- discover:
- runs-on: macos-latest
- outputs:
- projects: ${{ steps.collect.outputs.projects }}
- skipped: ${{ steps.collect.outputs.skipped }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Collect & filter Desktop platform project files
- id: collect
- shell: bash
- run: |
- set -e
- # Ensure jq is available (macOS image usually has it, fallback to brew)
- if ! command -v jq >/dev/null 2>&1; then
- echo "jq not found, installing via Homebrew";
- brew update >/dev/null 2>&1 || true
- brew install jq >/dev/null 2>&1
- fi
- # Find all Desktop platform csproj files: **/Platforms/Desktop/*.csproj (portable without mapfile)
- desktop_projects_tmp=$(mktemp)
- find . -type f -path '*/Platforms/Desktop/*.csproj' | sort > "$desktop_projects_tmp"
- if [ ! -s "$desktop_projects_tmp" ]; then
- echo "No Desktop platform projects found."
- echo "projects=[]" >> "$GITHUB_OUTPUT"
- echo "skipped=[]" >> "$GITHUB_OUTPUT"
- exit 0
- fi
- echo "Testing restore for discovered Desktop projects:"
- success_tmp=$(mktemp)
- skipped_tmp=$(mktemp)
- while IFS= read -r proj; do
- echo "Attempting restore: $proj"
- if dotnet restore "$proj" >/dev/null 2>&1; then
- echo " OK $proj"
- echo "$proj" >> "$success_tmp"
- else
- echo " SKIP (restore failed) $proj"
- echo "$proj" >> "$skipped_tmp"
- fi
- done < "$desktop_projects_tmp"
- if [ ! -s "$success_tmp" ]; then
- echo "No projects restored successfully.";
- echo "projects=[]" >> "$GITHUB_OUTPUT"
- else
- json=$(jq -R . < "$success_tmp" | jq -s -c .)
- echo "projects=$json" >> "$GITHUB_OUTPUT"
- fi
- if [ -s "$skipped_tmp" ]; then
- skipped_json=$(jq -R . < "$skipped_tmp" | jq -s -c .)
- echo "skipped=$skipped_json" >> "$GITHUB_OUTPUT"
- else
- echo "skipped=[]" >> "$GITHUB_OUTPUT"
- fi
- echo "Restore filtering complete.";
- echo "Successful projects:"; cat "$success_tmp" || true
- echo "Skipped projects:"; cat "$skipped_tmp" || true
- rm -f "$desktop_projects_tmp" "$success_tmp" "$skipped_tmp"
- build-desktop-bundles:
- needs: discover
- if: ${{ needs.discover.outputs.projects != '[]' && needs.discover.outputs.projects != '' }}
- runs-on: macos-latest
- env:
- MGFXC_WINE_PATH: /Users/runner/.winemonogame
- DYLD_LIBRARY_PATH: /usr/lib:/usr/local/lib:/opt/homebrew/lib:/usr/local/bin
- strategy:
- fail-fast: false
- matrix:
- project: ${{ fromJson(needs.discover.outputs.projects) }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup .NET 8
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: |
- 8.0.x
- - name: Setup for MonoGame
- uses: infinitespace-studios/monogame-actions/[email protected]
- - name: Install MonoPack
- run: dotnet tool install --global MonoPack
- - name: Build and Package Desktop Bundle
- id: package
- continue-on-error: true
- shell: bash
- run: |
- set -e
- PROJ="${{ matrix.project }}"
- NAME=$(basename "$PROJ" .csproj)
- PROJ_DIR=$(dirname "$PROJ")
- ARTIFACTS_DIR="./artifacts/$NAME"
- echo "Project path: $PROJ"
- echo "Project name: $NAME"
- echo "Project directory: $PROJ_DIR"
- echo "Output directory: $ARTIFACTS_DIR"
- # Check for macOS assets
- INFO_PLIST="$PROJ_DIR/Info.plist"
- ICNS_FILE="$PROJ_DIR/${NAME}.icns"
- if [ ! -f "$INFO_PLIST" ]; then
- echo "Error: Info.plist not found at $INFO_PLIST"
- echo "Please run ./generate-macos-assets.sh to generate macOS assets"
- exit 1
- fi
- echo "Packaging $NAME for all desktop platforms"
- if [ -f "$ICNS_FILE" ]; then
- echo "Using icon file: $ICNS_FILE"
- monopack -p "$PROJ" \
- -o "$ARTIFACTS_DIR" \
- -rids win-x64,linux-x64,osx-x64,osx-arm64 \
- -i "$INFO_PLIST" \
- -c "$ICNS_FILE" \
- -v \
- --macos-universal
- else
- echo "No .icns file found, packaging without custom icon"
- monopack -p "$PROJ" \
- -o "$ARTIFACTS_DIR" \
- -rids win-x64,linux-x64,osx-x64,osx-arm64 \
- -i "$INFO_PLIST" \
- -v \
- --macos-universal
- fi
- echo "Generated artifacts:"
- find "$ARTIFACTS_DIR" -type f -name "*.zip" || echo "No zip files found"
- ls -la "$ARTIFACTS_DIR" || echo "Artifacts directory not found"
- echo "name=$NAME" >> "$GITHUB_OUTPUT"
- - name: Record Build Result
- if: always()
- shell: bash
- run: |
- PROJ="${{ matrix.project }}"
- NAME=$(basename "$PROJ" .csproj)
- RESULT_DIR="./build-results"
- mkdir -p "$RESULT_DIR"
- if [ "${{ steps.package.outcome }}" = "success" ]; then
- jq -n --arg project "$NAME" --arg status "success" --arg error "" \
- '{project: $project, status: $status, error: $error}' > "$RESULT_DIR/$NAME.json"
- else
- # Capture the error - this is a simplified version, actual error would be in logs
- jq -n --arg project "$NAME" --arg status "failure" --arg error "Build or packaging failed - see job logs for details" \
- '{project: $project, status: $status, error: $error}' > "$RESULT_DIR/$NAME.json"
- fi
- - name: Upload Build Result
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: build-result-${{ steps.package.outputs.name }}
- path: build-results/*.json
- retention-days: 1
- - name: Upload Windows Bundle
- if: steps.package.outcome == 'success'
- uses: actions/upload-artifact@v4
- with:
- name: ${{ steps.package.outputs.name }}-Windows
- path: artifacts/${{ steps.package.outputs.name }}/*-win-x64.zip
- if-no-files-found: error
- retention-days: 14
- - name: Upload Linux Bundle
- if: steps.package.outcome == 'success'
- uses: actions/upload-artifact@v4
- with:
- name: ${{ steps.package.outputs.name }}-Linux
- path: artifacts/${{ steps.package.outputs.name }}/*-linux-x64.tar.gz
- if-no-files-found: error
- retention-days: 14
- - name: Upload macOS App Bundle
- if: steps.package.outcome == 'success'
- uses: actions/upload-artifact@v4
- with:
- name: ${{ steps.package.outputs.name }}-macOS-Universal
- path: artifacts/${{ steps.package.outputs.name }}/*-universal.tar.gz
- if-no-files-found: error
- retention-days: 14
- summary:
- needs: [discover, build-desktop-bundles]
- if: always()
- runs-on: macos-latest
- steps:
- - name: Download Build Results
- if: needs.discover.outputs.projects != '[]' && needs.discover.outputs.projects != ''
- uses: actions/download-artifact@v4
- with:
- pattern: build-result-*
- path: build-results
- merge-multiple: true
- - name: Build Summary
- shell: bash
- run: |
- echo "# Desktop Sample Build Summary" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- # Process build results if they exist
- if [ -d "build-results" ] && [ "$(ls -A build-results 2>/dev/null)" ]; then
- echo "## Build Results" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "| Project | Status | Error |" >> $GITHUB_STEP_SUMMARY
- echo "|---------|--------|-------|" >> $GITHUB_STEP_SUMMARY
- success_count=0
- failure_count=0
- for result_file in build-results/*.json; do
- if [ -f "$result_file" ]; then
- project=$(jq -r '.project' "$result_file")
- status=$(jq -r '.status' "$result_file")
- error=$(jq -r '.error' "$result_file")
- if [ "$status" = "success" ]; then
- echo "| $project | ✅ Success | - |" >> $GITHUB_STEP_SUMMARY
- success_count=$((success_count + 1))
- else
- echo "| $project | ❌ Failed | $error |" >> $GITHUB_STEP_SUMMARY
- failure_count=$((failure_count + 1))
- fi
- fi
- done
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Summary:** $success_count succeeded, $failure_count failed" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- elif [ "${{ needs.discover.outputs.projects }}" = "[]" ] || [ -z "${{ needs.discover.outputs.projects }}" ]; then
- echo "No Desktop platform projects were built (no successful restores)." >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
- # Show skipped projects
- if [ -n "${{ needs.discover.outputs.skipped }}" ] && [ "${{ needs.discover.outputs.skipped }}" != "[]" ]; then
- echo "## Skipped Projects (Restore Failed)" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "${{ needs.discover.outputs.skipped }}" | jq -r '.[]' | while read -r proj; do
- name=$(basename "$proj" .csproj)
- echo "- ⏭️ $name" >> $GITHUB_STEP_SUMMARY
- done
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
- echo "---" >> $GITHUB_STEP_SUMMARY
- echo "Cross-platform bundles (Windows, Linux, macOS) are available as separate artifacts for successful builds." >> $GITHUB_STEP_SUMMARY
|