4646 unity : 2021.3.45f2
4747 changeset : 88f88f591b2e
4848 runner : [self-hosted, macOS, ARM64]
49- - target : StandaloneLinux64
50- backend : IL2CPP
51- unity : 2021.3.45f2
52- changeset : 88f88f591b2e
53- runner : [self-hosted, X64, Linux]
54- - target : StandaloneLinux64
55- backend : Mono2x
56- unity : 2021.3.45f2
57- changeset : 88f88f591b2e
58- runner : [self-hosted, X64, Linux]
5949 - target : StandaloneWindows64
6050 backend : IL2CPP
6151 unity : 6000.4.0f1
@@ -194,25 +184,6 @@ jobs:
194184 Write-Host "Verified VC.Tools at: $($state.VcTools)"
195185 Write-Host "Verified Win10 SDK at: $($state.Win10Sdk)"
196186
197- - name : Verify IL2CPP toolchain (Linux)
198- if : runner.os == 'Linux' && matrix.backend == 'IL2CPP'
199- shell : bash
200- run : |
201- # IL2CPP's C++ to native step links against gcc/g++ + glibc-dev (the
202- # build-essential package on Ubuntu). Without these, Unity fails late
203- # inside the IL2CPP build with a cryptic linker error. Fail fast here
204- # with a clear remediation message instead.
205- MISSING=""
206- for cmd in gcc g++; do
207- command -v "$cmd" >/dev/null 2>&1 || MISSING="${MISSING:+$MISSING+}$cmd"
208- done
209- if [ -n "$MISSING" ]; then
210- echo "::error::IL2CPP toolchain incomplete on runner: $MISSING. Run on the runner host: sudo apt install -y build-essential"
211- exit 1
212- fi
213- echo "gcc: $(gcc --version | head -1)"
214- echo "g++: $(g++ --version | head -1)"
215-
216187 - name : Resolve Unity ${{ matrix.unity }} (macOS)
217188 if : runner.os == 'macOS'
218189 shell : bash
@@ -309,79 +280,6 @@ jobs:
309280 if ('${{ matrix.backend }}' -eq 'IL2CPP') { Write-Host "Found IL2CPP: $il2cpp" }
310281 "UNITY_PATH=$editor" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
311282
312- - name : Resolve Unity ${{ matrix.unity }} (Linux)
313- if : runner.os == 'Linux'
314- shell : bash
315- env :
316- UNITY_VER : ${{ matrix.unity }}
317- UNITY_CS : ${{ matrix.changeset }}
318- run : |
319- set -uo pipefail
320- HUB="unityhub"
321-
322- echo "::group::install editor"
323- "$HUB" --headless install \
324- --version "$UNITY_VER" --changeset "$UNITY_CS" --architecture x86_64 \
325- || echo "(install non-zero, OK if 'Editor already installed in this location')"
326- echo "::endgroup::"
327-
328- if [ "${{ matrix.backend }}" = "IL2CPP" ]; then
329- echo "::group::install linux-il2cpp module"
330- "$HUB" --headless install-modules \
331- --version "$UNITY_VER" --changeset "$UNITY_CS" --architecture x86_64 \
332- --module linux-il2cpp \
333- || echo "(install-modules non-zero, OK if 'No modules found to install')"
334- echo "::endgroup::"
335- fi
336-
337- EDITOR_PATH="$HOME/Unity/Hub/Editor/$UNITY_VER/Editor/Unity"
338-
339- IL2CPP_DIR=""
340- if [ "${{ matrix.backend }}" = "IL2CPP" ] && [ -x "$EDITOR_PATH" ]; then
341- IL2CPP_DIR="$HOME/Unity/Hub/Editor/$UNITY_VER/Editor/Data/PlaybackEngines/LinuxStandaloneSupport/Variations/linux64_player_nondevelopment_il2cpp"
342- [ -d "$IL2CPP_DIR" ] || IL2CPP_DIR=""
343- fi
344-
345- MISSING=""
346- [ -x "$EDITOR_PATH" ] || MISSING="editor"
347- [ "${{ matrix.backend }}" = "IL2CPP" ] && [ -z "$IL2CPP_DIR" ] && MISSING="${MISSING:+$MISSING+}linux-il2cpp"
348- if [ -n "$MISSING" ]; then
349- echo "::error::Unity $UNITY_VER missing: $MISSING"
350- ls -la "$HOME/Unity/Hub/Editor/" 2>&1 || true
351- "$HUB" --headless editors --installed 2>&1 || true
352- exit 1
353- fi
354-
355- echo "Found Unity: $EDITOR_PATH"
356- [ -n "$IL2CPP_DIR" ] && echo "Found IL2CPP: $IL2CPP_DIR"
357- echo "UNITY_PATH=$EDITOR_PATH" >> "$GITHUB_ENV"
358-
359- - name : Activate Unity license (Linux)
360- if : runner.os == 'Linux'
361- shell : bash
362- env :
363- UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
364- UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
365- UNITY_SERIAL : ${{ secrets.UNITY_SERIAL }}
366- run : |
367- set -uo pipefail
368- LOG="$(mktemp)"
369- echo "::group::Activate Unity"
370- "$UNITY_PATH" -batchmode -nographics -quit \
371- -username "$UNITY_EMAIL" \
372- -password "$UNITY_PASSWORD" \
373- -serial "$UNITY_SERIAL" \
374- -logFile - 2>&1 | tee "$LOG" || true
375- echo "::endgroup::"
376-
377- if grep -qE "(Successfully activated the entitlement license|Successfully processed license management request)" "$LOG"; then
378- echo "Unity license is active"
379- exit 0
380- fi
381-
382- echo "::error::Unity activation failed. Check UNITY_EMAIL/UNITY_PASSWORD/UNITY_SERIAL secrets and seat-pool availability."
383- exit 1
384-
385283 - name : Run PlayMode tests (macOS)
386284 if : runner.os == 'macOS'
387285 shell : bash
@@ -431,26 +329,6 @@ jobs:
431329 Write-Host "Unity exited with code $exit"
432330 if ($exit -ne 0) { exit $exit }
433331
434- - name : Run PlayMode tests (Linux)
435- if : runner.os == 'Linux'
436- shell : bash
437- env :
438- AUDIENCE_TEST_PUBLISHABLE_KEY : ${{ secrets.AUDIENCE_TEST_PUBLISHABLE_KEY }}
439- AUDIENCE_SCRIPTING_BACKEND : ${{ matrix.backend }}
440- run : |
441- set -euo pipefail
442- mkdir -p artifacts
443- # Mirrors the macOS variant: tee Unity's stdout to artifacts/unity.log
444- # so the annotation step has a file to scan while progress streams to
445- # the job log. pipefail propagates Unity's exit code through tee.
446- "$UNITY_PATH" \
447- -batchmode -nographics \
448- -projectPath examples/audience \
449- -runTests \
450- -testPlatform ${{ matrix.target }} \
451- -testResults "$(pwd)/artifacts/test-results.xml" \
452- -logFile - 2>&1 | tee "$(pwd)/artifacts/unity.log"
453-
454332 - name : Mark workspace safe for git (Windows)
455333 if : always() && runner.os == 'Windows'
456334 shell : pwsh
@@ -491,21 +369,6 @@ jobs:
491369 }
492370 }
493371
494- - name : Capture player log (Linux)
495- if : always() && runner.os == 'Linux'
496- shell : bash
497- run : |
498- # See macOS counterpart for rationale. Linux player log location:
499- # ~/.config/unity3d/<CompanyName>/<ProductName>/Player.log (Unity's
500- # standard persistent data path on Linux, matching $XDG_CONFIG_HOME).
501- mkdir -p artifacts
502- src="$HOME/.config/unity3d"
503- if [ -d "$src" ]; then
504- find "$src" -name "Player.log" 2>/dev/null | while IFS= read -r f; do
505- cp "$f" "artifacts/Player-$(basename "$(dirname "$f")").log" 2>/dev/null || true
506- done
507- fi
508-
509372 - name : Surface Unity compile errors as annotations (macOS)
510373 if : always() && runner.os == 'macOS'
511374 shell : bash
@@ -551,23 +414,6 @@ jobs:
551414 Write-Host "::error::$sanitized"
552415 }
553416
554- - name : Surface Unity compile errors as annotations (Linux)
555- if : always() && runner.os == 'Linux'
556- shell : bash
557- run : |
558- set -uo pipefail
559- # See macOS counterpart for rationale.
560- LOG_FILE="artifacts/unity.log"
561- if [ ! -f "$LOG_FILE" ]; then
562- echo "::notice::No Unity log file at $LOG_FILE."
563- exit 0
564- fi
565- grep -E '(error CS[0-9]+:|Compilation failed:)' "$LOG_FILE" | sort -u | while IFS= read -r line; do
566- trimmed="${line#"${line%%[![:space:]]*}"}"
567- sanitized="${trimmed//::/%3A%3A}"
568- echo "::error::$sanitized"
569- done || true
570-
571417 - name : Publish test report
572418 uses : dorny/test-reporter@v3
573419 if : always()
@@ -587,6 +433,66 @@ jobs:
587433 artifacts/Player-*.log
588434 examples/audience/Logs/**
589435
436+ # Linux PlayMode runs on GitHub-hosted Ubuntu via GameCI Docker, not on the
437+ # self-hosted matrix above, to keep self-hosted machines free for Win/macOS.
438+ playmode-linux :
439+ if : github.event.pull_request.head.repo.fork == false || github.event_name == 'workflow_dispatch'
440+ name : ${{ matrix.target }} / ${{ matrix.backend }} / Unity ${{ matrix.unity }}
441+ runs-on : ubuntu-latest-8-cores
442+ strategy :
443+ fail-fast : false
444+ matrix :
445+ include :
446+ - target : StandaloneLinux64
447+ backend : IL2CPP
448+ unity : 2021.3.45f2
449+ - target : StandaloneLinux64
450+ backend : Mono2x
451+ unity : 2021.3.45f2
452+
453+ steps :
454+ - uses : actions/checkout@v4
455+ with :
456+ lfs : true
457+
458+ - uses : actions/cache@v4
459+ with :
460+ path : examples/audience/Library
461+ key : Library-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}-${{ hashFiles('examples/audience/Assets/**', 'examples/audience/Packages/**', 'examples/audience/ProjectSettings/**', 'src/Packages/Audience/**') }}
462+ restore-keys : |
463+ Library-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}-
464+ Library-${{ matrix.backend }}-${{ matrix.target }}-
465+
466+ - uses : game-ci/unity-test-runner@v4
467+ id : playmode
468+ env :
469+ UNITY_EMAIL : ${{ secrets.UNITY_EMAIL }}
470+ UNITY_PASSWORD : ${{ secrets.UNITY_PASSWORD }}
471+ UNITY_SERIAL : ${{ secrets.UNITY_SERIAL }}
472+ AUDIENCE_TEST_PUBLISHABLE_KEY : ${{ secrets.AUDIENCE_TEST_PUBLISHABLE_KEY }}
473+ AUDIENCE_SCRIPTING_BACKEND : ${{ matrix.backend }}
474+ with :
475+ unityVersion : ${{ matrix.unity }}
476+ targetPlatform : ${{ matrix.target }}
477+ projectPath : examples/audience
478+ testMode : playmode
479+ githubToken : ${{ secrets.GITHUB_TOKEN }}
480+
481+ - name : Publish test report
482+ uses : dorny/test-reporter@v3
483+ if : always()
484+ with :
485+ name : PlayMode (${{ matrix.backend }} / ${{ matrix.target }})
486+ path : ${{ steps.playmode.outputs.artifactsPath }}/playmode-results.xml
487+ reporter : dotnet-nunit
488+ fail-on-error : true
489+
490+ - uses : actions/upload-artifact@v4
491+ if : always()
492+ with :
493+ name : playmode-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}
494+ path : ${{ steps.playmode.outputs.artifactsPath }}
495+
590496 # Mobile IL2CPP build validation — runs on GitHub-hosted Ubuntu via GameCI Docker
591497 # containers so self-hosted macOS/Windows machines are not occupied.
592498 # Scope: IL2CPP compile pipeline only. Runtime tests require a real device and
0 commit comments