Skip to content

Feature-parity audit: cli's Docker/native build scripts diverged from unity-builder's real source #65

Description

@frostebite

Context

While auditing cli for other regressions after finding and fixing the Docker commands-ignored bug (#61) and the native macOS build's completely-missing env-var passthrough (#64), I systematically diffed cli's build scripts (dist/platforms/**) against unity-builder's real, current source — safely preserved in game-ci/unity-engine-core's extraction — rather than guessing. cli's implementation is a from-scratch rewrite with its own copy of these assets, and it has genuinely drifted from the original in several concrete ways beyond what's already been fixed this session.

Already fixed, not part of this list: #61 (Docker commands passthrough), #62 (--manualExit/-quit — confirmed this was actually a regression, unity-builder already had this exact feature), #63 (return_license reimport), #64 (native macOS build env passthrough + missing floating-license branch).

Everything below is real, confirmed by direct diff against unity-engine-core's copy — not speculative. None of it is implemented yet; I deliberately didn't rush all of it in without a way to verify against real Unity/Docker builds. Filing this as one issue per the pattern of game-ci/roadmap#11; split into sub-issues as they're picked up.

Findings, by severity

1. Unity 6 Build Profiles entirely unsupported (ubuntu/mac/windows build scripts)

Real unity-builder supports Unity 6's Build Profile feature end-to-end:

  • A BUILD_PROFILE env var, echoed at build start.
  • -buildTarget conditionally omitted when a build profile is set (the profile determines the platform instead).
  • -customBuildProfile "$BUILD_PROFILE" and -activeBuildProfile flags passed to the editor.

cli has none of this — no BUILD_PROFILE env var, no conditional -buildTarget, no -customBuildProfile/-activeBuildProfile flags, on any of the three platforms. Any project using Unity 6 build profiles can't use them via cli.

Scope to fix: new --build-profile CLI option → BUILD_PROFILE env var (reuse the pattern from --manualExit/MANUAL_EXIT in #62) → update build.sh (ubuntu/mac) and build.ps1 (windows) to match unity-builder's exact conditional structure. Purely additive — safe when the option is unset.

2. RUN_AS_HOST_USER (self-hosted runner permission handling) — completely absent

Real unity-builder's entrypoint.sh (Linux) supports running the whole build as a dynamically-created user matching the host's UID/GID (via useradd/su) instead of always running as root — specifically for self-hosted runners, to avoid every build artifact ending up root-owned on the host. cli's entrypoint.sh has no equivalent: it always runs as root, unconditionally.

Scope to fix: this is the largest, riskiest item here — it restructures the entrypoint's execution flow (user creation, su switching, /dev/stdout//dev/stderr permission handling). Needs careful review and ideally a self-hosted-runner-like test environment before landing, not a blind port.

3. Android SDK target-version auto-detection — only the manual-params path exists

Real unity-builder's entrypoint.sh (Linux), when ANDROID_SDK_MANAGER_PARAMETERS is not explicitly set, auto-detects the target SDK version by parsing AndroidTargetSdkVersion out of the project's ProjectSettings/ProjectSettings.asset and invokes sdkmanager "platforms;android-$targetAPI" directly. cli's build.sh only handles the case where ANDROID_SDK_MANAGER_PARAMETERS is explicitly provided — no fallback auto-detection.

Scope to fix: moderate. Needs the sdkmanager binary discovery logic too (real source checks cmdline-tools then falls back to tools/bin) — cli currently assumes a fixed path via unity-editor.d.

4. Personal-license machine-ID randomization (Linux) — missing entirely

Real unity-builder's entrypoint.sh randomizes /etc/machine-id via dbus-uuidgen when UNITY_SERIAL starts with F (personal license activation), specifically to avoid machine-binding collisions between concurrent runner containers sharing a host. cli has no equivalent.

This is directly relevant to the class of bug reported in #28 (which I closed as out-of-scope for cli, pointing at game-ci/docker's base image) — worth revisiting now that it's clear unity-builder does have a mitigation for this exact failure mode that cli dropped.

Scope to fix: small, mechanical, safe — a few lines in entrypoint.sh, gated on UNITY_SERIAL prefix.

5. Windows: .upmconfig.toml copy, VC++ 2013 Redistributables, and ENABLE_GPU/llvmpipe support — all missing

Real unity-builder's entrypoint.ps1 does three things cli's doesn't:

  • Copies .upmconfig.toml from C:\githubhome (private package registry auth) into the user profile.
  • Installs VC++ 2013 Redistributables via choco install vcredist2013 — a known, documented fix for Unity failing on GitHub-hosted Windows runners due to a missing runtime dependency.
  • If ENABLE_GPU=true, downloads and installs a Mesa llvmpipe software graphics driver (self-contained script, install_llvmpipe.ps1) for GPU-less compute-shader/graphics testing.

cli has none of these. The two install scripts (install_vcredist13.ps1, install_llvmpipe.ps1) don't exist in cli's dist/platforms/windows/ at all.

Scope to fix: moderate — port the two self-contained install scripts verbatim (low risk, they're standalone and gated), wire ENABLE_GPU through as a new CLI option, add the unconditional VC++ redist install and .upmconfig.toml copy to entrypoint.ps1.

6. Mac entrypoint: unconditional mkdir on a possibly-already-existing directory

cli's mac/entrypoint.sh does sudo mkdir /Library/Application\ Support/Unity (no -p) — this errors if the directory already exists, e.g. on a reused self-hosted macOS runner where a previous run's cleanup didn't fully complete. Real unity-builder guards this with if [ ! -d "$UNITY_LICENSE_PATH" ] before creating it.

Scope to fix: trivial, one-line, zero-risk (mkdirmkdir -p, or add the existence check to match real unity-builder exactly).

7. SKIP_ACTIVATION support — missing on all platforms

Real unity-builder supports skipping the activate/return-license steps entirely via SKIP_ACTIVATION=true (useful when a license is already active in a long-lived container, e.g. self-hosted runners with persistent state). cli has no equivalent anywhere.

Scope to fix: small, additive — new CLI option, gate the activate/return-license calls in each platform's entrypoint.

Suggested approach

Not all of these are equal risk/value — recommend tackling in roughly this order:

  1. CLI: Host capabilities #6 (mkdir -p) — trivial, do it immediately, no reason to wait.
  2. Create CLI #4 (machine-id randomization) — small, safe, directly closes a real-world failure mode.
  3. Introduce CLI / Introduce Deno #1 (Build Profiles) — well-scoped, purely additive, real Unity 6 feature gap.
  4. CLI: Command/Jobs system #7 (SKIP_ACTIVATION) — small, additive.
  5. CLI: Running a build locally #5 (Windows VC++/llvmpipe/upmconfig) — moderate, self-contained scripts to port.
  6. chore: add development.md #3 (Android SDK auto-detect) — moderate.
  7. prepare dist folder for bfg #2 (RUN_AS_HOST_USER) — largest and riskiest, do last and with the most scrutiny/testing.

None of this was found via speculation — every item above is a direct diff against unity-builder's real, current source, safely available via unity-engine-core. Cross-linking game-ci/roadmap#11 (workstream 2) since this is exactly the kind of drift that motivated the destination-repo consolidation in the first place.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions