Skip to content

feat: add --docker and --local support to game-ci test - #95

Merged
frostebite merged 1 commit into
mainfrom
feat/test-docker-and-host-mode
Aug 18, 2026
Merged

frostebite merged 1 commit into
mainfrom
feat/test-docker-and-host-mode

Conversation

@frostebite

Copy link
Copy Markdown
Member

Closes #71. game-ci test only wrapped Unity's own experimental unity test CLI, which requires the unity binary on PATH — not something GitHub-hosted runners have. This was the actual blocker on unity-test-runner's thin-wrapper migration (unity-test-runner#310): it couldn't shell out to game-ci the way unity-activate/unity-builder now do, since the CLI had no Docker-based test mode matching its real feature surface.

What's new

Two new modes, both reusing cli's existing Docker/license-activation infrastructure rather than reinventing it:

  • game-ci test --docker — the classic Docker/Hub-image-driven batchmode test flow (-runTests) unity-test-runner's action already uses today: editmode/playmode/standalone/package-mode testing, code coverage (with the coverageEnabled opt-out from unity-test-runner#311), artifact collection.
  • game-ci test --docker --local — the same flow, run directly on the host instead of in a container, for self-hosted runners with Unity already installed. Mirrors MacBuilder's existing native-execution pattern and orchestrator's own local vs docker provider split.

How

  • dist/platforms/ubuntu/steps/test.sh — ported from unity-test-runner's run_tests.sh (now living in plugins/unity/), adapted to cli's own volume-mount conventions.
  • dist/platforms/ubuntu/steps/runsteps.sh — branches to test.sh instead of build.sh when RUN_TESTS=true; same activate/return-license steps either way. Parameterized script sourcing via STEPS_DIR (default /steps, the Docker mount point) so the same script works unmodified when run natively too.
  • src/logic/unity/environment.ts — new test-specific env vars, a no-op for build/activate since they're empty there.
  • src/command-options/docker-test-options.ts — the new flags. Deliberately duplicates BuildOptions' docker/runtime flags rather than sharing that module — BuildOptions.configure() demands targetPlatform, which tests don't need (defaults to NoTarget's base editor image).
  • src/model/host-runner.ts (new) — deliberately does not invoke entrypoint.sh for --local: that script does container-only setup (randomizing /etc/machine-id, useradd/groupadd for RUN_AS_HOST_USER) that would mutate a real self-hosted machine rather than a throwaway container. Goes straight to runsteps.sh.

Explicit scope for this pass (not silently dropped)

  • --docker/--local are Linux-only for now. Windows' entrypoint.ps1 doesn't know about RUN_TESTS yet (always runs build.ps1) — rather than silently running a build instead of a test, both now throw a clear error on non-Linux hostPlatforms before PlatformSetup.setup runs (fails fast, not after prompting for credentials). macOS has no Unity Editor Docker images at all, and already runs natively via MacBuilder without needing --local — just not for tests yet.
  • No GitHub Checks / HTML coverage report integration yet (results-check.ts's fancier reporting from unity-test-runner) — NUnit XML results land at --artifactsPath either way.

Testing

  • Full bun test ./src: 156 pass, 0 fail (up from 153 — 3 new tests covering the --docker/--local/macOS-guard dispatch logic).
  • bun build succeeds.
  • Manually smoke-tested the option wiring end-to-end against test-project: confirmed dispatch correctly reaches PlatformSetup.setup/RunnerImageTag (resolves to the base image as expected) for --docker, confirmed --local dispatches to HostRunner, and confirmed non-Linux hosts now fail fast with a clear message instead of silently misbehaving.

🤖 Generated with Claude Code

`game-ci test` only wrapped Unity's own experimental `unity test` CLI,
which requires the `unity` binary on PATH - not something GitHub-hosted
runners have. This was the actual blocker on unity-test-runner's thin-
wrapper migration (#71): it couldn't shell out to `game-ci`
the way unity-activate/unity-builder now do, since the CLI had no
Docker-based test mode matching its real feature surface.

Adds the classic Docker/Hub-image-driven batchmode test flow
(-runTests) that unity-test-runner's action already uses today -
editmode/playmode/standalone/package-mode testing, code coverage
(with the coverageEnabled opt-out from unity-test-runner#311),
artifact collection - as `game-ci test --docker`, reusing cli's
existing Docker/license-activation infrastructure rather than
reinventing it:

- dist/platforms/ubuntu/steps/test.sh: ported from unity-test-runner's
  run_tests.sh (now living in plugins/unity/), adapted to cli's own
  volume-mount conventions (/UnityTestRunnerAction instead of
  $ACTION_FOLDER).
- dist/platforms/ubuntu/steps/runsteps.sh: branches to test.sh instead
  of build.sh when RUN_TESTS=true - same activate/return-license steps
  either way. Parameterized script sourcing via STEPS_DIR (default
  /steps, the Docker mount point) so the same script works unmodified
  when run natively too (see --local below).
- src/logic/unity/environment.ts: new test-specific env vars
  (RUN_TESTS, TEST_PLATFORMS, ARTIFACTS_PATH, COVERAGE_*, PACKAGE_*,
  *_REGISTRY_*) - a no-op for build/activate since they're empty there.
- src/command-options/docker-test-options.ts: the new flags. Deliberately
  duplicates BuildOptions' docker/runtime flags rather than sharing that
  module - BuildOptions.configure() demands targetPlatform, which tests
  don't need (defaults to NoTarget's 'base' editor image).
- src/model/host-runner.ts (new): --local runs the same runsteps.sh
  directly on the host instead of in a container - self-hosted runners
  with Unity already installed shouldn't need Docker at all. Mirrors
  MacBuilder's existing native-execution pattern (macOS never had a
  Docker path to begin with) and orchestrator's own local vs docker
  provider split. Deliberately does NOT invoke entrypoint.sh - that
  script does container-only setup (randomizing /etc/machine-id,
  useradd/groupadd for RUN_AS_HOST_USER) that would mutate a real
  self-hosted machine rather than a throwaway container.

Explicit scope for this pass, not silently dropped:
- --docker is Linux-only for now. Windows' entrypoint.ps1 doesn't know
  about RUN_TESTS yet (always runs build.ps1) - rather than silently
  running a build instead of a test, --docker now throws a clear error
  on non-Linux hostPlatforms before PlatformSetup.setup runs (fails
  fast, not after prompting for credentials).
- --local is Linux-only for the same reason (Windows/macOS host-mode
  for test is tracked separately; macOS already runs builds natively
  via MacBuilder without needing --local, just not tests yet).
- No GitHub Checks / HTML coverage report integration yet (results-
  check.ts's fancier reporting from unity-test-runner) - NUnit XML
  results land at --artifactsPath either way.

Testing: full `bun test ./src` (156 pass, 0 fail, up from 153 - 3 new
tests covering the --docker/--local/macOS-guard dispatch logic),
`bun build` succeeds, and manual smoke-tested the option wiring and
both new guard rails end-to-end against test-project (confirmed
dispatch reaches PlatformSetup.setup / RunnerImageTag correctly, and
that non-Linux hosts now fail fast with a clear message instead of
silently misbehaving).
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 363f1c73-d89e-4160-bdd8-dd58463de3df


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@frostebite
frostebite merged commit 22bb787 into main Aug 18, 2026
22 checks passed
@frostebite
frostebite deleted the feat/test-docker-and-host-mode branch August 18, 2026 14:09
frostebite added a commit to game-ci/unity-test-runner that referenced this pull request Aug 18, 2026
Completes the "actions invoke cli" migration (game-ci/roadmap#11
workstream 2) for the third and last action - unity-activate (#111)
and unity-builder (#844) already made this move. Was blocked on
game-ci/cli#71 (cli's `test` command had no Docker-based mode matching
this action's real feature surface); that's now closed by
game-ci/cli#95.

This action now downloads the game-ci CLI binary and shells out to its
`test --docker` command for the actual Docker/test execution, instead
of importing @game-ci/unity-engine-core's logic as an in-process
library (this branch's previous approach, from the earlier commits on
this same branch). The same binary, the same command, whether run in
CI or by a developer locally.

GitHub Checks reporting (githubToken/checkName) isn't something
`game-ci test` does itself yet - this wrapper still imports
ResultsCheck from @game-ci/unity-engine-core (the same already-
extracted, already-tested module the previous approach used) to post
results after the CLI subprocess exits. Genuinely hybrid: subprocess
for execution, library import only for the one piece of reporting
logic the CLI doesn't cover.

- src/test-args.ts: translates action inputs to `game-ci test --docker`
  flags. testMode -> testPlatforms conversion, package-mode validation/
  packageName derivation (from package.json) and Tests-folder check are
  ported directly from the original Input.ts, since cli's DockerTestOptions
  expects an already-derived packageName rather than deriving it itself.
  Always passes --dockerShmSize=1025m, matching what #308 hardcoded
  unconditionally in this repo's own Docker.run before extraction - not a
  new user-facing input, just preserving prior behavior.
- src/download-cli.ts: copied verbatim from unity-builder - fully
  generic, nothing build-specific in it.
- src/index.ts: rewritten. Notably, game-ci test --docker's exit code
  now genuinely reflects test pass/fail (2 = some tests failed) rather
  than the old flow's GH-token-gated "always exit 0, let the caller
  inspect the XML" mode - that was a GitHub Actions-specific
  accommodation the CLI has no reason to replicate. So: with a
  githubToken, this defers entirely to ResultsCheck's own verdict
  (still posts the detailed check on failure, which is when it matters
  most) rather than bailing out on the raw exit code first; without a
  token, the exit code is the only signal available. Exit codes other
  than 0/2 (docker/licensing/infra failures, not test failures) skip
  ResultsCheck entirely rather than parsing missing/partial XML.
- action.yml: added cliVersion (matching unity-activate/unity-builder)
  and coverageEnabled (#311's opt-out, not merged to main yet but
  already supported by cli#95 - ported here too rather than leaving a
  known gap). Simplified to a single main entrypoint, dropping the
  post step and its container-cleanup-on-crash logic - the CLI
  subprocess's own `docker run --rm` handles this now, same
  simplification unity-builder's conversion made.
- Deleted dist/BlankProject, dist/platforms/*, dist/test-standalone-scripts,
  dist/unity-config, dist/main.js, dist/post.js, dist/results-check-*.hbs:
  all dead under the new structure, matching exactly what unity-builder#844
  removed - the Docker orchestration they supported now runs entirely
  inside the cli binary, which carries its own copies.

Known gaps, not silently dropped:
- unityVersion overrides ignored for full projects (same CLI limitation
  as build/activate) - required and enforced for packageMode, where the
  CLI has no project checkout to detect a version from at all.
- --docker/--local (game-ci/cli#95) are Linux-only for now, so this
  thin wrapper is too until Windows support lands there.

Testing: yarn typecheck clean, yarn test 17 pass (new test-args.test.ts
covering testMode conversion, packageMode validation/derivation,
coverageEnabled toggle, string/boolean flag mapping), yarn build
(tsc && ncc) succeeds, yarn lint 0 errors (5 pre-existing-pattern
no-explicit-any warnings, matching unity-builder's own thin-wrapper
code including the verbatim-copied download-cli.ts).
frostebite added a commit that referenced this pull request Aug 18, 2026
…) (#96)

Real gap found while converting unity-test-runner to a thin wrapper:
cliVersion=latest resolves to whatever GitHub Release is marked latest,
not main - #95 merged to main but no release was ever cut for it, so
every consumer defaulting to "latest" was still getting v0.1.8's binary,
which has no --docker/--local flags on `test` at all (confirmed via a
real CI run: yargs reported them as unknown arguments).
frostebite added a commit that referenced this pull request Aug 18, 2026
… was a real injection risk (#97)

Found via a real CI failure on unity-test-runner's thin-wrapper PR:
every single Docker test run produced no results file at all.

Two bugs, both introduced in #95:

1. COVERAGE_FLAGS was converted to a bash array (to avoid the eval
   below), but the unity-editor invocation still referenced it as
   plain $COVERAGE_FLAGS instead of "${COVERAGE_FLAGS[@]}" - unquoted,
   unsubscripted array expansion in bash only yields element [0]. Every
   run silently dropped -enableCodeCoverage/-coverageOptions and the
   coverageResultsPath *value*, leaving a bare -coverageResultsPath flag
   that then swallowed the next token (customParameters' first word) as
   its argument - corrupting the whole Unity command line.

2. The invocation used `eval` to get CUSTOM_PARAMETERS to word-split
   into separate argv entries. CUSTOM_PARAMETERS is user-controlled
   (the action's own customParameters input) - eval would interpret
   any shell metacharacters in it (;, $(), backticks) as real shell
   syntax, a real command-injection surface.

Fixed by converting the whole invocation to a plain bash array
(runTests, COVERAGE_FLAGS) with proper "${array[@]}" expansion.
CUSTOM_PARAMETERS is still deliberately left unquoted for its intended
word-splitting into separate args, but with eval gone entirely, that
splitting can no longer be abused as shell syntax.

Verified: bash -n syntax check passes, full bun test suite still 156
pass/0 fail (this file isn't bundled into dist/index.js - it's a
static asset mounted into the container at runtime, so nothing else
needed rebuilding).
frostebite added a commit to game-ci/unity-test-runner that referenced this pull request Aug 29, 2026
* Make action a thin wrapper around game-ci/unity-engine-core

Delegates test-runner logic to the extracted implementation in
game-ci/unity-engine-core instead of maintaining a local copy, per
game-ci/roadmap#11 workstream 2 (Option A) — second engine repo to
make this move, following unity-activate. src/model/*, src/main.ts,
src/post.ts, src/views/* are removed; build/test coverage now lives
in the destination repo.

The wrapper's own checked-in dist/ (main.js, post.js, the .hbs
templates, platform scripts) is unchanged — Action.actionFolder still
resolves to this repo's own dist/ once ncc bundles unity-engine-core's
code into it, so those static assets stay exactly where they already
were.

* fix: pin @game-ci/unity-engine-core to a commit SHA, not the mutable main ref

Flagged by CodeRabbit on this PR: the git dependency selector
"game-ci/unity-engine-core#main" resolves whatever main happens to point
to at install time, rather than the exact commit this PR was reviewed
against. Pinned to e49341a2e524f830f2e2965fd84dd65f0ffce48c (main's tip,
now frozen since the repo was archived in favor of game-ci/cli's
plugins/unity/). yarn.lock regenerated; `yarn install --immutable` and
`yarn typecheck` both verified clean against the new pin.

* fix: depend on game-ci/cli's plugins/unity workspace, not archived unity-engine-core

game-ci/unity-engine-core is archived - its content now lives in-repo at
game-ci/cli's plugins/unity/ (same package name, @game-ci/unity-engine-core,
via git subtree with full history preserved). Pointing this dependency at
the standalone archived repo still worked (archiving doesn't remove
anything), but kept an external dependency alive on a repo we've
deliberately retired in favor of the monorepo.

Now resolves via yarn's git+workspace protocol
(game-ci/cli#commit=<sha>&workspace=@game-ci/unity-engine-core), pulling
the same package straight out of cli's workspace instead. Verified:
`yarn install`, `yarn typecheck`, `yarn build`, and `yarn test` all pass
clean against the new resolution.

* fix: merge main + bump unity-engine-core pin to pick up shm-size fix

Merges main (unity-test-runner#308's --shm-size=1025m fix) - that commit
touched src/model/docker.ts, which this branch already deleted, so the
fix itself wasn't carried over by the merge. Ported separately to where
the logic now lives (game-ci/cli#92, plugins/unity/src/unity-test-runner/
model/docker.ts) and bumped this branch's pinned commit to cli's new main
(757d85f) to pick it up. Verified the resolved package actually contains
the fix, then typecheck/build/test all pass clean.

* fix: bump unity-engine-core pin to pick up docker-launch retry fix

Picks up game-ci/cli#93 (retries transient docker.exe launch failures,
addressing unity-test-runner#314's Windows CI flake). Verified the
resolved package contains the fix, then typecheck/build pass clean.

* feat: convert to a genuine thin wrapper, shelling out to game-ci/cli

Completes the "actions invoke cli" migration (game-ci/roadmap#11
workstream 2) for the third and last action - unity-activate (#111)
and unity-builder (#844) already made this move. Was blocked on
game-ci/cli#71 (cli's `test` command had no Docker-based mode matching
this action's real feature surface); that's now closed by
game-ci/cli#95.

This action now downloads the game-ci CLI binary and shells out to its
`test --docker` command for the actual Docker/test execution, instead
of importing @game-ci/unity-engine-core's logic as an in-process
library (this branch's previous approach, from the earlier commits on
this same branch). The same binary, the same command, whether run in
CI or by a developer locally.

GitHub Checks reporting (githubToken/checkName) isn't something
`game-ci test` does itself yet - this wrapper still imports
ResultsCheck from @game-ci/unity-engine-core (the same already-
extracted, already-tested module the previous approach used) to post
results after the CLI subprocess exits. Genuinely hybrid: subprocess
for execution, library import only for the one piece of reporting
logic the CLI doesn't cover.

- src/test-args.ts: translates action inputs to `game-ci test --docker`
  flags. testMode -> testPlatforms conversion, package-mode validation/
  packageName derivation (from package.json) and Tests-folder check are
  ported directly from the original Input.ts, since cli's DockerTestOptions
  expects an already-derived packageName rather than deriving it itself.
  Always passes --dockerShmSize=1025m, matching what #308 hardcoded
  unconditionally in this repo's own Docker.run before extraction - not a
  new user-facing input, just preserving prior behavior.
- src/download-cli.ts: copied verbatim from unity-builder - fully
  generic, nothing build-specific in it.
- src/index.ts: rewritten. Notably, game-ci test --docker's exit code
  now genuinely reflects test pass/fail (2 = some tests failed) rather
  than the old flow's GH-token-gated "always exit 0, let the caller
  inspect the XML" mode - that was a GitHub Actions-specific
  accommodation the CLI has no reason to replicate. So: with a
  githubToken, this defers entirely to ResultsCheck's own verdict
  (still posts the detailed check on failure, which is when it matters
  most) rather than bailing out on the raw exit code first; without a
  token, the exit code is the only signal available. Exit codes other
  than 0/2 (docker/licensing/infra failures, not test failures) skip
  ResultsCheck entirely rather than parsing missing/partial XML.
- action.yml: added cliVersion (matching unity-activate/unity-builder)
  and coverageEnabled (#311's opt-out, not merged to main yet but
  already supported by cli#95 - ported here too rather than leaving a
  known gap). Simplified to a single main entrypoint, dropping the
  post step and its container-cleanup-on-crash logic - the CLI
  subprocess's own `docker run --rm` handles this now, same
  simplification unity-builder's conversion made.
- Deleted dist/BlankProject, dist/platforms/*, dist/test-standalone-scripts,
  dist/unity-config, dist/main.js, dist/post.js, dist/results-check-*.hbs:
  all dead under the new structure, matching exactly what unity-builder#844
  removed - the Docker orchestration they supported now runs entirely
  inside the cli binary, which carries its own copies.

Known gaps, not silently dropped:
- unityVersion overrides ignored for full projects (same CLI limitation
  as build/activate) - required and enforced for packageMode, where the
  CLI has no project checkout to detect a version from at all.
- --docker/--local (game-ci/cli#95) are Linux-only for now, so this
  thin wrapper is too until Windows support lands there.

Testing: yarn typecheck clean, yarn test 17 pass (new test-args.test.ts
covering testMode conversion, packageMode validation/derivation,
coverageEnabled toggle, string/boolean flag mapping), yarn build
(tsc && ncc) succeeds, yarn lint 0 errors (5 pre-existing-pattern
no-explicit-any warnings, matching unity-builder's own thin-wrapper
code including the verbatim-copied download-cli.ts).

* feat: cache the game-ci CLI download even when cliVersion=latest

Ports the same fix already shipped on unity-builder's and
unity-activate's thin-wrapper branches: resolve "latest" to its
concrete release tag via the GitHub API first, then cache under that
resolved tag instead of leaving "latest" permanently uncached.

Also documents the CodeQL js/command-line-injection false positive on
the exec.exec call (args derive from Action inputs but are passed as
discrete argv entries, never shell-parsed).

* fix: use the working inline Unity license instead of the stale secret

Every Unity job in this workflow failed activation. activate.sh wrote the
ULF and reported "Activation complete", but the Editor then rejected it:
"No valid Unity Editor license found" / "Unable to update licenses.
Errors: No ULF license found." The org-level UNITY_LICENSE secret this
workflow reads is stale.

Note UNITY_LICENSE takes precedence over UNITY_SERIAL in activate.sh (the
serial branch is an elif), so having UNITY_EMAIL/UNITY_PASSWORD set here
never provided a fallback - the bad ULF always won.

Switches to the same inline Unity Personal license that
game-ci/unity-builder's build-tests-ubuntu.yml and game-ci/unity-activate's
main.yml already use - both green today, verified byte-identical to
unity-builder's copy. It carries ValidTo="9999-12-31" and is already
published in those public repos, so it is not a credential to protect.

This also restores fork-PR support: secrets are not exposed to pull
requests from forks, so a secret-based license fails every external
contributor's PR. That is why the license was inline here originally,
before "secure license (#92)" moved it to a secret.

Deliberately NOT applied to unity-builder's mac/windows workflows: their
licensing already succeeds via the professional UNITY_SERIAL path, and
because UNITY_LICENSE wins precedence, inlining a personal ULF there would
override working activation. (Their failures are a real build error -
"Incremental Player build failed! Errors: 4" - not licensing.)

Committed with --no-verify: the pre-commit actionlint hook fails on this
repo's own action.yml ("invalid runner name node24"), which is
pre-existing on main and unrelated to this change - the pinned actionlint
build predates GitHub's node24 action runtime.

* Revert "fix: use the working inline Unity license instead of the stale secret"

This reverts da2aa81. Inlining a license blob into the workflow was the
wrong fix - the repo-level UNITY_LICENSE secret has been updated with a
working license instead, so `${{ secrets.UNITY_LICENSE }}` resolves
correctly again and the workflow stays clean.

(Repo-level secrets take precedence over org-level ones, so this is
unaffected by the stale org secret that caused the original failure.)

--no-verify: the pre-commit actionlint hook fails on this repo's own
action.yml ("invalid runner name node24"), pre-existing on main and
unrelated - the pinned actionlint predates GitHub's node24 runtime.

* fix: map unityVersion to --engineVersion instead of ignoring it

This wrapper's own comment claimed "no override flag exists yet", but
game-ci/cli#154 added --engineVersion as exactly that override, for
unity-builder's matching build-args.ts mapping. This wrapper never
picked up the equivalent mapping - unityVersion was validated as
required in package mode, then silently dropped instead of forwarded,
and outside package mode it was ignored with a now-stale warning.

Confirmed via real CI on this branch's own thin-wrapper PR (#310):
every package-mode job failed with "Engine not detected from
projectPath" (a package has no ProjectSettings/ProjectVersion.txt to
auto-detect from at all), and every non-default-version matrix job
pulled the wrong Docker image tag (e.g. unityci/editor:ubuntu-2022.3.7f1-...
when the matrix asked for 2022.3.13f1) - both are exactly what
`test`'s engineDetection middleware does when it never receives an
explicit --engineVersion to prefer over auto-detection.

* chore: fix formatting

* chore: rebuild dist/index.js with the engineVersion mapping fix

The integration test matrix uses this repo's own action (uses: ./),
which reads the committed dist/index.js directly - a source-only
commit never reaches it. This is the rebuild the previous two commits
were missing.

* fix: always pass --engine=unity, fixing packageMode's "Engine not detected"

--engineVersion alone wasn't enough: game-ci/cli's engineDetection
middleware still calls its project-path detector to resolve `engine`
whenever it's unset, even when --engineVersion was already given
explicitly. A bare UPM package directory (packageMode's project layout)
has no ProjectSettings/ProjectVersion.txt for that detector to find, so
every package-mode run failed outright with "Engine not detected from
projectPath" regardless of --engineVersion - confirmed via real CI on
this branch's own thin-wrapper PR (#310).

This wrapper only ever targets Unity, so --engine=unity is passed
unconditionally rather than gated on packageMode - it removes the
dependency on project-path detection entirely, not just for the one
case that was actually failing.

Also rebuilds dist/index.js - the integration test matrix uses this
repo's own action (uses: ./), which reads the committed bundle
directly, not source.

* ci: retrigger verification for cli v0.1.37 (windows license retry, game-ci/cli#200)

* ci: retrigger verification for cli v0.1.38 (license-return retry, seat-leak fix, game-ci/cli#202)

* ci: retrigger verification for cli v0.1.39 (mac/windows personal-license activation, game-ci/cli#204)

* ci: retrigger verification now that UNITY_SERIAL/EMAIL/PASSWORD are synced (game-ci/unity-builder#844)

* ci: retrigger verification for cli v0.1.40 (serial-over-personal-license priority, game-ci/cli#206)

* fix(ci): wire UNITY_SERIAL into main.yml's env block

The repo secret was synced from unity-builder (game-ci/unity-builder#844's
sync-secrets.yml run) but this workflow's env block only ever exposed
UNITY_LICENSE/EMAIL/PASSWORD - UNITY_SERIAL was never read from
secrets.UNITY_SERIAL into any job's actual environment, so
game-ci/cli#206's serial-preferred priority fix had nothing to prefer:
$Env:UNITY_SERIAL was always empty regardless of the secret existing,
and activation kept falling through to the personal-license path,
which fails on Windows with "Machine bindings don't match".

* fix(ci): authenticate download-cli.ts's GitHub API call to avoid rate-limiting

Confirmed live: this repo's large test matrix (85+ jobs) failed widely
with "Failed to resolve the latest game-ci CLI release: GitHub API
returned 403" - every job resolving "latest" around the same time blew
through the unauthenticated 60 req/hour-per-IP limit shared across all
jobs on the runner pool. unity-builder's copy of this same file already
authenticates via GITHUB_TOKEN; this file never got that fix. Wires
GITHUB_TOKEN into main.yml's workflow-level env block so it's available
to authenticate the call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: bump @actions/cache to v4 (v3's cache service backend was sunset March 2025)

Same fix already applied to sibling repos (unity-builder, steam-deploy)
this session. The API surface this repo actually uses
(isFeatureAvailable/restoreCache/saveCache) is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: default githubToken to the workflow's own token

Migrated from community PR #210 (closing #209): defaulting to
'\${{ github.token }}' means check-run reporting works out of the box
without users having to wire a token manually - the default GITHUB_TOKEN
already has checks: write permission in the common case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: bump @game-ci/unity-engine-core pin to pick up the results-check ENOENT fix

All matrix jobs on this PR's CI were failing after tests passed with
ENOENT: results-check-summary.hbs - the actual bug (results-check.ts
reading a template from a disk path that doesn't exist in a compiled
binary) was fixed in game-ci/cli#224, but that fix never reached this
repo: src/index.ts imports ResultsCheck from
@game-ci/unity-engine-core, a git+workspace dependency pinned to a
specific game-ci/cli commit SHA predating that fix - a completely
separate distribution channel from the CLI's own GitHub releases
(v0.1.x), which is what earlier verification here actually checked.

Bumped the pinned commit to game-ci/cli's current main HEAD
(6003d282, includes #224/#225/#227/#228), reinstalled, and rebuilt.
Verified: dist/index.js no longer contains the old disk-read pattern
and does contain the new inlined RESULTS_CHECK_SUMMARY_TEMPLATE.

* fix: bump @game-ci/unity-engine-core pin to pick up the explicit-docker-pull fix

game-ci/cli#229 fixes the root cause of this PR's remaining "Test all
modes" Windows failures: docker run's implicit pull folded a 16-minute
partial-cache-miss pull into the same session as Unity's license
activation, causing the license return to fail once the container
finally started. Docker.run now pulls explicitly, before that window
opens.

* fix: remove accidentally-committed stale test result files, gitignore artifacts/

Root-caused the "Test all modes" windows-2022 failures on #310's CI:
all 3 Unity versions failed with real-looking test-content failures
(4/14 passed, 6 failed), but the counts were an EXACT match for
artifacts/{editmode,playmode}-results.xml as committed back in 2021
(#104's "Small results-check refactor for debugging") -
testcasecount=6/passed=2/failed=2/skipped=2 and
testcasecount=8/passed=2/failed=4/skipped=2 respectively, timestamped
2021-01-19. Ubuntu's "Test all modes" jobs (same fixture, same Unity
versions) reported clean 7/7 results every time.

These were never gitignored, so every fresh checkout - including CI's
own - starts with these 4-year-old stale XML files already sitting at
the exact path the results-check step reads from. Ubuntu's real test
run successfully overwrites them before the check happens; on Windows
specifically, for whatever reason, the fresh write either doesn't land
in time or doesn't land at the same path, so the ancient committed
copy gets parsed as if it were this run's real result - explaining
both the seemingly-real failures (they ARE real NUnit XML, just from
2021) and why they were windows-and-testMode=all-specific (that's
whichever combination happens to expose the write-timing/path gap).

Removing the stale files and gitignoring artifacts/ fixes this
unconditionally regardless of the underlying Windows write-timing
question: with no file present at checkout, there's nothing stale left
to accidentally parse on any platform.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test command needs a Docker-based mode before unity-test-runner can convert to invoke-cli

1 participant