Skip to content

ci: the MSVC gate checks that cl.exe exists, not that it can run #336

Description

What the gate checks today

scripts/unity/assert-msvc-toolchain.ps1 decides an IL2CPP host is usable when
cl.exe exists at the newest MSVC toolset path:

-ProbeExecutable { param($path) Test-Path -LiteralPath $path -PathType Leaf }

That is what #333 needed: the version directory was present, Unity discovered it
and put it on PATH, and cl.exe was absent — so the build died twenty minutes
later with a message naming neither the host nor the cause.

What it does not catch

A cl.exe that is present but cannot start — truncated by a failed update,
blocked by security tooling, missing a sibling DLL. The gate reports the host
healthy and the leg fails later, having already taken a Unity licence seat and
the organization build lock.

Why it was not simply added

A launch probe (cl.exe /?, treating any launch failure as unusable) has real
ways to fail on a healthy host:

  • cl.exe resolves sibling DLLs (mspdb*, msvcp*) from its own directory, and
    the toolchain is normally invoked under vcvars;
  • this gate runs before the organization build lock, so a false failure
    blocks every IL2CPP leg on that runner, not just one job.

That is the same shape as the vswhere defect fixed in #331, where a discovery
failure was reported as a missing toolchain and would have told a healthy
runner's administrator to reinstall the C++ workload.

The asymmetry is what settled it for now: missing cl.exe is the failure that
actually happened and presence catches it; corrupt-but-present is rarer and still
fails the build, just later and more expensively.

What a fix needs

Not a blind change — a Windows host where both cases can be demonstrated:

  1. healthy toolchain: confirm the chosen probe exits 0 outside a vcvars
    environment, invoked by full path, as the gate would invoke it;
  2. corrupted toolchain (rename a sibling DLL, or truncate cl.exe): confirm the
    probe fails;
  3. add both to scripts/__tests__/test-msvc-toolchain.ps1 via the existing
    ProbeExecutable seam, which already makes the decision testable off Windows;
  4. keep the failure message distinguishing "no toolset", "compiler missing", and
    "compiler present but unusable" — the operator fix differs for each.

If step 1 cannot be made reliable, the correct outcome is to close this and keep
the presence check, with the reasoning recorded.

Raised by GitHub Copilot on #331.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions