Skip to content

Commit 5d17c81

Browse files
ci(audience-sdk): add PlayMode test workflow [SDK-148]
Four-cell matrix builds the audience sample app and runs PlayMode tests inside the built player across both backends: - StandaloneWindows64 / IL2CPP / windows-latest / Unity 2021.3.45f2 - StandaloneWindows64 / Mono2x / windows-latest / Unity 2021.3.45f2 - StandaloneOSX / IL2CPP / macos-latest / Unity 2021.3.45f2 - StandaloneOSX / Mono2x / macos-latest / Unity 2021.3.45f2 Backend selection per cell goes through AUDIENCE_SCRIPTING_BACKEND env var consumed by the ScriptingBackendOverride Editor script. Notes: - Both targets use Windows / macOS hosts because game-ci can cross- build Windows IL2CPP players on Linux but the runner can't launch them to drive PlayMode tests; the host OS must match the player target. - Unity 2021.3.45f2 (not 2021.3.26f1 as originally planned) avoids a zlib-vs-macOS-15-SDK toolchain incompatibility that breaks the IL2CPP build under newer Xcode CLT (Unity zutil.h:147 macros fdopen to NULL, collides with stdio.h fdopen function declaration). - Tests live-fire to sandbox via AUDIENCE_TEST_PUBLISHABLE_KEY repo secret. Skipped on fork PRs to avoid secret leakage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7d72558 commit 5d17c81

6 files changed

Lines changed: 344 additions & 3 deletions

File tree

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Audience SDK — PlayMode (IL2CPP + Mono)
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'src/Packages/Audience/**'
7+
- 'examples/audience/**'
8+
- '.github/workflows/test-audience-sample-app.yml'
9+
workflow_dispatch:
10+
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
playmode:
17+
if: github.event.pull_request.head.repo.fork == false || github.event_name == 'workflow_dispatch'
18+
name: ${{ matrix.target }} / ${{ matrix.backend }} / Unity ${{ matrix.unity }}
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
include:
23+
- target: StandaloneWindows64
24+
backend: IL2CPP
25+
unity: 2021.3.45f2
26+
changeset: 88f88f591b2e
27+
runner: [self-hosted, Windows, X64]
28+
- target: StandaloneWindows64
29+
backend: Mono2x
30+
unity: 2021.3.45f2
31+
changeset: 88f88f591b2e
32+
runner: [self-hosted, Windows, X64]
33+
- target: StandaloneOSX
34+
backend: IL2CPP
35+
unity: 2021.3.45f2
36+
changeset: 88f88f591b2e
37+
runner: [self-hosted, macOS, ARM64]
38+
- target: StandaloneOSX
39+
backend: Mono2x
40+
unity: 2021.3.45f2
41+
changeset: 88f88f591b2e
42+
runner: [self-hosted, macOS, ARM64]
43+
runs-on: ${{ matrix.runner }}
44+
timeout-minutes: 60
45+
46+
steps:
47+
- uses: actions/checkout@v4
48+
with:
49+
lfs: true
50+
51+
- name: Cache Unity Library
52+
uses: actions/cache@v4
53+
with:
54+
path: examples/audience/Library
55+
key: Library-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}-${{ hashFiles('examples/audience/Assets/**', 'examples/audience/Packages/**', 'examples/audience/ProjectSettings/**', 'src/Packages/Audience/**') }}
56+
restore-keys: |
57+
Library-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}-
58+
Library-${{ matrix.backend }}-${{ matrix.target }}-
59+
60+
- name: Resolve Unity ${{ matrix.unity }} (macOS)
61+
if: runner.os == 'macOS'
62+
shell: bash
63+
env:
64+
UNITY_VER: ${{ matrix.unity }}
65+
UNITY_CS: ${{ matrix.changeset }}
66+
run: |
67+
set -uo pipefail
68+
HUB="/Applications/Unity Hub.app/Contents/MacOS/Unity Hub"
69+
70+
echo "::group::install editor"
71+
"$HUB" -- --headless install \
72+
--version "$UNITY_VER" --changeset "$UNITY_CS" --architecture arm64 \
73+
|| echo "(install non-zero — OK if 'Editor already installed in this location')"
74+
echo "::endgroup::"
75+
76+
echo "::group::install mac-il2cpp module"
77+
"$HUB" -- --headless install-modules \
78+
--version "$UNITY_VER" --changeset "$UNITY_CS" --architecture arm64 \
79+
--module mac-il2cpp \
80+
|| echo "(install-modules non-zero — OK if 'No modules found to install')"
81+
echo "::endgroup::"
82+
83+
EDITOR_APP=""
84+
for cand in \
85+
"/Applications/Unity/Hub/Editor/$UNITY_VER-arm64/Unity.app" \
86+
"/Applications/Unity/Hub/Editor/$UNITY_VER/Unity.app"; do
87+
if [ -x "$cand/Contents/MacOS/Unity" ]; then EDITOR_APP="$cand"; break; fi
88+
done
89+
90+
IL2CPP_DIR=""
91+
if [ -n "$EDITOR_APP" ]; then
92+
for d in \
93+
"$EDITOR_APP/Contents/PlaybackEngines/MacStandaloneSupport/Variations/macos_arm64_player_nondevelopment_il2cpp" \
94+
"$EDITOR_APP/Contents/PlaybackEngines/MacStandaloneSupport/Variations/macos_x64_player_nondevelopment_il2cpp"; do
95+
if [ -d "$d" ]; then IL2CPP_DIR="$d"; break; fi
96+
done
97+
fi
98+
99+
if [ -z "$EDITOR_APP" ] || [ -z "$IL2CPP_DIR" ]; then
100+
echo "::error::Unity $UNITY_VER + Mac-IL2CPP not present after install attempt"
101+
ls -la /Applications/Unity/Hub/Editor/ 2>&1 || true
102+
"$HUB" -- --headless editors --installed 2>&1 || true
103+
exit 1
104+
fi
105+
106+
echo "Found Unity: $EDITOR_APP/Contents/MacOS/Unity"
107+
echo "Found IL2CPP: $IL2CPP_DIR"
108+
echo "UNITY_PATH=$EDITOR_APP/Contents/MacOS/Unity" >> "$GITHUB_ENV"
109+
110+
- name: Resolve Unity ${{ matrix.unity }} (Windows)
111+
if: runner.os == 'Windows'
112+
shell: pwsh
113+
env:
114+
UNITY_VER: ${{ matrix.unity }}
115+
UNITY_CS: ${{ matrix.changeset }}
116+
run: |
117+
$hub = "C:\Program Files\Unity Hub\Unity Hub.exe"
118+
119+
Write-Host "::group::install editor"
120+
& $hub -- --headless install --version $env:UNITY_VER --changeset $env:UNITY_CS
121+
if ($LASTEXITCODE -ne 0) { Write-Host "(install non-zero — OK if 'Editor already installed in this location')" }
122+
$global:LASTEXITCODE = 0
123+
Write-Host "::endgroup::"
124+
125+
Write-Host "::group::install windows-il2cpp module"
126+
& $hub -- --headless install-modules --version $env:UNITY_VER --changeset $env:UNITY_CS --module windows-il2cpp
127+
if ($LASTEXITCODE -ne 0) { Write-Host "(install-modules non-zero — OK if 'No modules found to install')" }
128+
$global:LASTEXITCODE = 0
129+
Write-Host "::endgroup::"
130+
131+
$editor = "C:\Program Files\Unity\Hub\Editor\$env:UNITY_VER\Editor\Unity.exe"
132+
$il2cpp = "C:\Program Files\Unity\Hub\Editor\$env:UNITY_VER\Editor\Data\PlaybackEngines\windowsstandalonesupport\Variations\win64_player_nondevelopment_il2cpp"
133+
if (-not (Test-Path $editor) -or -not (Test-Path $il2cpp)) {
134+
Write-Host "::error::Unity $env:UNITY_VER + Windows-IL2CPP not present after install attempt"
135+
Get-ChildItem "C:\Program Files\Unity\Hub\Editor\" -ErrorAction SilentlyContinue | Format-Table
136+
& $hub -- --headless editors --installed
137+
exit 1
138+
}
139+
140+
Write-Host "Found Unity: $editor"
141+
Write-Host "Found IL2CPP: $il2cpp"
142+
"UNITY_PATH=$editor" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
143+
144+
- name: Run PlayMode tests (macOS)
145+
if: runner.os == 'macOS'
146+
shell: bash
147+
env:
148+
AUDIENCE_TEST_PUBLISHABLE_KEY: ${{ secrets.AUDIENCE_TEST_PUBLISHABLE_KEY }}
149+
AUDIENCE_SCRIPTING_BACKEND: ${{ matrix.backend }}
150+
run: |
151+
set -euo pipefail
152+
mkdir -p artifacts
153+
"$UNITY_PATH" \
154+
-batchmode -nographics \
155+
-projectPath examples/audience \
156+
-runTests \
157+
-testPlatform ${{ matrix.target }} \
158+
-testResults "$(pwd)/artifacts/test-results.xml" \
159+
-logFile -
160+
161+
- name: Run PlayMode tests (Windows)
162+
if: runner.os == 'Windows'
163+
shell: pwsh
164+
env:
165+
AUDIENCE_TEST_PUBLISHABLE_KEY: ${{ secrets.AUDIENCE_TEST_PUBLISHABLE_KEY }}
166+
AUDIENCE_SCRIPTING_BACKEND: ${{ matrix.backend }}
167+
run: |
168+
New-Item -ItemType Directory -Force -Path artifacts | Out-Null
169+
& $env:UNITY_PATH `
170+
-batchmode -nographics `
171+
-projectPath examples/audience `
172+
-runTests `
173+
-testPlatform ${{ matrix.target }} `
174+
-testResults "$pwd\artifacts\test-results.xml" `
175+
-logFile -
176+
if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 2) { exit $LASTEXITCODE }
177+
178+
- name: Publish test report
179+
uses: dorny/test-reporter@v3
180+
if: always()
181+
with:
182+
name: PlayMode (${{ matrix.backend }} / ${{ matrix.target }})
183+
path: artifacts/test-results.xml
184+
reporter: dotnet-nunit
185+
fail-on-error: false
186+
187+
- uses: actions/upload-artifact@v4
188+
if: always()
189+
with:
190+
name: playmode-${{ matrix.backend }}-${{ matrix.target }}-${{ matrix.unity }}
191+
path: |
192+
artifacts/test-results.xml
193+
examples/audience/Logs/**

examples/audience/Assets/SampleApp/Tests/Runtime/SampleAppLiveFireTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public IEnumerator InitTrackFlush_AgainstSandbox_FlushReportsOk()
132132
}
133133

134134
[UnityTest]
135-
public IEnumerator TypedEvent_Progression_FlushReportsOk()
135+
public IEnumerator Event_Progression_FlushReportsOk()
136136
{
137137
// Progression's only required field is `status` (enum, defaults to "start").
138138
yield return DriveTypedEventAndFlush(SampleAppUi.Buttons.TypedEvent("progression"));

examples/audience/Packages/manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"com.unity.test-framework": "1.1.33",
1010
"com.unity.textmeshpro": "3.0.6",
1111
"com.unity.timeline": "1.6.5",
12+
"com.unity.toolchain.macos-arm64-linux-x86_64": "2.0.5",
1213
"com.unity.ugui": "1.0.0",
1314
"com.unity.visualscripting": "1.9.4",
1415
"com.unity.modules.ai": "1.0.0",

examples/audience/Packages/packages-lock.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@
8080
"dependencies": {},
8181
"url": "https://packages.unity.com"
8282
},
83+
"com.unity.sysroot": {
84+
"version": "2.0.10",
85+
"depth": 1,
86+
"source": "registry",
87+
"dependencies": {},
88+
"url": "https://packages.unity.com"
89+
},
90+
"com.unity.sysroot.linux-x86_64": {
91+
"version": "2.0.9",
92+
"depth": 1,
93+
"source": "registry",
94+
"dependencies": {
95+
"com.unity.sysroot": "2.0.10"
96+
},
97+
"url": "https://packages.unity.com"
98+
},
8399
"com.unity.test-framework": {
84100
"version": "1.1.33",
85101
"depth": 0,
@@ -122,6 +138,16 @@
122138
},
123139
"url": "https://packages.unity.com"
124140
},
141+
"com.unity.toolchain.macos-arm64-linux-x86_64": {
142+
"version": "2.0.5",
143+
"depth": 0,
144+
"source": "registry",
145+
"dependencies": {
146+
"com.unity.sysroot": "2.0.10",
147+
"com.unity.sysroot.linux-x86_64": "2.0.9"
148+
},
149+
"url": "https://packages.unity.com"
150+
},
125151
"com.unity.ugui": {
126152
"version": "1.0.0",
127153
"depth": 0,

examples/audience/ProjectSettings/ProjectSettings.asset

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,12 +632,12 @@ PlayerSettings:
632632
PS4: 1
633633
PS5: 1
634634
Stadia: 1
635+
Standalone: 3
635636
WebGL: 1
636637
Windows Store Apps: 1
637638
XboxOne: 1
638639
iPhone: 1
639640
tvOS: 1
640-
Standalone: 3
641641
incrementalIl2cppBuild: {}
642642
suppressCommonWarnings: 1
643643
allowUnsafeCode: 0
@@ -727,7 +727,7 @@ PlayerSettings:
727727
framebufferDepthMemorylessMode: 0
728728
qualitySettingsNames: []
729729
projectName: audience
730-
organizationId:
730+
organizationId:
731731
cloudEnabled: 0
732732
legacyClampBlendShapeWeights: 0
733733
playerDataPath:
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
{
2+
"templatePinStates": [],
3+
"dependencyTypeInfos": [
4+
{
5+
"userAdded": false,
6+
"type": "UnityEngine.AnimationClip",
7+
"defaultInstantiationMode": 0
8+
},
9+
{
10+
"userAdded": false,
11+
"type": "UnityEditor.Animations.AnimatorController",
12+
"defaultInstantiationMode": 0
13+
},
14+
{
15+
"userAdded": false,
16+
"type": "UnityEngine.AnimatorOverrideController",
17+
"defaultInstantiationMode": 0
18+
},
19+
{
20+
"userAdded": false,
21+
"type": "UnityEditor.Audio.AudioMixerController",
22+
"defaultInstantiationMode": 0
23+
},
24+
{
25+
"userAdded": false,
26+
"type": "UnityEngine.ComputeShader",
27+
"defaultInstantiationMode": 1
28+
},
29+
{
30+
"userAdded": false,
31+
"type": "UnityEngine.Cubemap",
32+
"defaultInstantiationMode": 0
33+
},
34+
{
35+
"userAdded": false,
36+
"type": "UnityEngine.GameObject",
37+
"defaultInstantiationMode": 0
38+
},
39+
{
40+
"userAdded": false,
41+
"type": "UnityEditor.LightingDataAsset",
42+
"defaultInstantiationMode": 0
43+
},
44+
{
45+
"userAdded": false,
46+
"type": "UnityEngine.LightingSettings",
47+
"defaultInstantiationMode": 0
48+
},
49+
{
50+
"userAdded": false,
51+
"type": "UnityEngine.Material",
52+
"defaultInstantiationMode": 0
53+
},
54+
{
55+
"userAdded": false,
56+
"type": "UnityEditor.MonoScript",
57+
"defaultInstantiationMode": 1
58+
},
59+
{
60+
"userAdded": false,
61+
"type": "UnityEngine.PhysicMaterial",
62+
"defaultInstantiationMode": 0
63+
},
64+
{
65+
"userAdded": false,
66+
"type": "UnityEngine.PhysicsMaterial2D",
67+
"defaultInstantiationMode": 0
68+
},
69+
{
70+
"userAdded": false,
71+
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
72+
"defaultInstantiationMode": 0
73+
},
74+
{
75+
"userAdded": false,
76+
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
77+
"defaultInstantiationMode": 0
78+
},
79+
{
80+
"userAdded": false,
81+
"type": "UnityEngine.Rendering.VolumeProfile",
82+
"defaultInstantiationMode": 0
83+
},
84+
{
85+
"userAdded": false,
86+
"type": "UnityEditor.SceneAsset",
87+
"defaultInstantiationMode": 1
88+
},
89+
{
90+
"userAdded": false,
91+
"type": "UnityEngine.Shader",
92+
"defaultInstantiationMode": 1
93+
},
94+
{
95+
"userAdded": false,
96+
"type": "UnityEngine.ShaderVariantCollection",
97+
"defaultInstantiationMode": 1
98+
},
99+
{
100+
"userAdded": false,
101+
"type": "UnityEngine.Texture",
102+
"defaultInstantiationMode": 0
103+
},
104+
{
105+
"userAdded": false,
106+
"type": "UnityEngine.Texture2D",
107+
"defaultInstantiationMode": 0
108+
},
109+
{
110+
"userAdded": false,
111+
"type": "UnityEngine.Timeline.TimelineAsset",
112+
"defaultInstantiationMode": 0
113+
}
114+
],
115+
"defaultDependencyTypeInfo": {
116+
"userAdded": false,
117+
"type": "<default_scene_template_dependencies>",
118+
"defaultInstantiationMode": 1
119+
},
120+
"newSceneOverride": 0
121+
}

0 commit comments

Comments
 (0)