Skip to content

ci(audience): run linux PlayMode under xvfb (SDK-317 / SDK-318)#768

Merged
ImmutableJeffrey merged 3 commits intomainfrom
chore/audience-linux-playmode-ci
May 10, 2026
Merged

ci(audience): run linux PlayMode under xvfb (SDK-317 / SDK-318)#768
ImmutableJeffrey merged 3 commits intomainfrom
chore/audience-linux-playmode-ci

Conversation

@ImmutableJeffrey
Copy link
Copy Markdown
Collaborator

Summary

  • Runs Linux audience PlayMode cells inside unityci/editor:ubuntu-*-linux-il2cpp-3 under xvfb. The previous game-ci/unity-test-runner@v4 hardcoded -nographics, so PlayMode tests came back inconclusive and silently passed.
  • Watchdog SIGTERMs Unity 30 s after the Test run completed log line so each Linux cell exits as soon as its suite finishes. 40-min hard cap as fallback.
  • -force-glcore at runtime skips Unity 6's Vulkan init and matches the Unity 2021.3 default GL path.
  • Hides the in-app log pane on Unity 6 Linux so llvmpipe stops rasterising UI Toolkit triangles per frame.
  • Drives the test matrix from matrix-shared.json so adding or removing a target only edits one file.
  • Per-platform install + playmode scripts under .github/scripts/audience/ (install-unity-windows.ps1, install-unity-macos.sh, playmode-windows.ps1, playmode-macos.sh, playmode-linux.sh host wrapper, playmode-linux-container.sh in-container body).
  • Step names show scope only when the step runs (e.g. Detect or Install Unity (StandaloneWindows64 only)); no suffix when the step is skipped.
  • Stamps [CI] buildGuid=... runId=... cellId=... into Player.log on player startup. CI-only via env vars.
  • Mirrors SDK output and OnError fires to Debug.Log so failures land in Player.log.
  • DiskStore.ReadBatch treats a missing queue directory as an empty queue. Matches existing guards.
  • Live-fire test SetUp ignores cleanup-time OnError fires so background flush cancellations do not fail unrelated tests.
  • Trims 30 unused packages and engine modules from the sample-app manifest. Smaller IL2CPP and Mono player binaries; faster Bee/Tundra build phases.

Linear: SDK-317, SDK-318

@ImmutableJeffrey ImmutableJeffrey force-pushed the chore/audience-linux-playmode-ci branch from 9a1379c to e68a7f2 Compare May 10, 2026 15:08
ImmutableJeffrey and others added 2 commits May 11, 2026 02:03
- Reworks playmode-linux to run inside a docker container under xvfb, via
  .github/scripts/audience/playmode-linux.sh. game-ci/unity-test-runner@v4
  hardcodes -nographics, so PlayMode tests came back inconclusive and silently
  passed.
- Watchdog SIGTERMs Unity 30s after "Test run completed" so cells exit on suite
  finish; handles Unity 6's known shutdown hang.
- -force-glcore at runtime skips the Unity 6 Vulkan init and matches the Unity
  2021.3 default path.
- Suppresses in-app log pane on Unity 6 Linux to skip llvmpipe rasterising UI
  Toolkit triangles per frame.
- Stamps CI build info into Player.log on player startup; gated to CI runs only.
- Mirrors SDK output and OnError fires to Debug.Log so failures land in
  Player.log.
- DiskStore.ReadBatch treats missing queue dir as empty (matches existing
  guards).
- Live-fire test SetUp ignores cleanup-time OnError fires so background flush
  cancellations do not fail unrelated tests.
- Trims 30 unused packages from the sample-app manifest.
- Extracts the macOS and Windows playmode runners and the Windows VS Build
  Tools setup to .github/scripts/, mirroring the Linux pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…SampleApp

Drops 30 of 39 manifest.json entries that the SampleApp does not use.
Verified by grepping the SampleApp source, the SampleApp scene, and
the Audience SDK runtime for any reference to each removed module or
package.

Removed packages:
- com.unity.textmeshpro: no TMP_Text or TMPro references
- com.unity.timeline: no PlayableDirector or TimelineAsset references
- com.unity.ugui: SampleApp uses UI Toolkit, no Canvas references
- com.unity.visualscripting: no ScriptMachine or graph references

Removed engine modules:
- ai, animation, assetbundle, cloth, director, imageconversion,
  particlesystem, physics, physics2d, screencapture, terrain,
  terrainphysics, tilemap, ui, umbra, unityanalytics, vehicles, video,
  vr, wind, xr: no runtime references in SampleApp or audience SDK
- unitywebrequestassetbundle, unitywebrequestaudio,
  unitywebrequesttexture, unitywebrequestwww: SDK uses
  System.Net.Http.HttpClient, not UnityWebRequest variants

Kept (verified used or required):
- com.immutable.audience: the SDK
- com.unity.test-framework: test runner
- com.unity.modules.androidjni: Android plugin compatibility
- com.unity.modules.audio: AudioListener present in SampleApp scene
- com.unity.modules.imgui: test runner overlay
- com.unity.modules.jsonserialize: defensive
- com.unity.modules.uielements: UI Toolkit, primary UI surface
- com.unity.modules.unitywebrequest: defensive (test framework)

Expected impact:
- Smaller IL2CPP and Mono player binaries.
- Faster IL2CPP compile and Bee/Tundra build phases on every cell.
- Faster project init (less to load, fewer InitializeOnLoad hooks).
- Per-frame UI Toolkit cost on llvmpipe is unchanged; that is targeted
  separately by PR #765's log-pane suppression.

Risk: a build link error on a platform that needs a removed module
shows immediately in CI; revert is one-line.
@ImmutableJeffrey ImmutableJeffrey force-pushed the chore/audience-linux-playmode-ci branch from ff27597 to dea2d97 Compare May 10, 2026 16:04
Removes the cached on-disk file counter and the BumpCount delta
tracking that maintained it. Count() now calls Directory.GetFiles
each time.

Why
- File.Delete silently succeeds when the path is missing, so
  TryDelete returned true regardless of whether a real file went
  away. Two concurrent flushes that both called Delete on the same
  paths each got true back and each called BumpCount(-1), drifting
  the cached count negative.
- Shutdown's force-clear of _sendInFlight followed by an ungated
  final SendBatchAsync gave the race a real opening (visible as
  the StatusBar_QueueSizeIncrementsAfterTrack flake on Linux Unity 6,
  where finalCount went past zero into "got -2").
- The cached counter was already documented as approximate ("Tests
  that plant files outside the DiskStore API will drift this and
  should assert on filesystem state, not Count()"), so callers
  could not rely on it anyway.

Trade-off: Count() is now O(N) on the queue directory. The only
caller is ImmutableAudience.QueueSize, read from a 500 ms UI poll
and a couple of test assertions, so this is fine for any realistic
queue size and removes an entire class of drift.

TryDelete drops its bool return because nothing needs to know
whether a real file was removed once we are not counting deltas.
@ImmutableJeffrey ImmutableJeffrey force-pushed the chore/audience-linux-playmode-ci branch from dea2d97 to ac25f26 Compare May 10, 2026 16:31
{
// Don't fail tests on cleanup-time OnError fires when in-flight HTTP
// gets cancelled. Errors still land in Player.log via Debug.LogError.
LogAssert.ignoreFailingMessages = true;
Copy link
Copy Markdown
Collaborator

@nattb8 nattb8 May 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should reset this in TearDown()?


// Emits a CDP marker row so this run's events can be filtered out of analytics.
[UnityTest]
public IEnumerator AudienceCiTestMarker_EmitsRunMetadata()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public IEnumerator AudienceCiTestMarker_EmitsRunMetadata()
public IEnumerator AudienceCiTestMarker_TrackDoesNotThrow()

Should this call flush after? so it actually sends? otherwise if you're just checking that it doesn't throw an exception, rename it to AudienceCiTestMarker_TrackDoesNotThrow

@ImmutableJeffrey ImmutableJeffrey marked this pull request as ready for review May 10, 2026 23:14
@ImmutableJeffrey ImmutableJeffrey requested review from a team as code owners May 10, 2026 23:14
-username "$UNITY_EMAIL" \
-password "$UNITY_PASSWORD" \
-serial "$UNITY_SERIAL" \
-logFile - 2>&1 | tee "$ACTIVATION_LOG" || true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: MEDIUM
The license activation command writes full activation output to artifacts/activation.log (... | tee "$ACTIVATION_LOG"), and this PR’s workflow uploads artifacts/** as a retained Actions artifact. That creates a new path for potentially sensitive Unity licensing/account details to leave the ephemeral runner and be broadly downloadable by artifact readers.

Impact: CI artifact consumers may gain access to sensitive activation/license metadata that should remain ephemeral.

@ImmutableJeffrey ImmutableJeffrey merged commit 6488498 into main May 10, 2026
39 checks passed
@ImmutableJeffrey ImmutableJeffrey deleted the chore/audience-linux-playmode-ci branch May 10, 2026 23:18
@github-actions github-actions Bot added the chore label May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants