Skip to content

test: probe custom Windows GPU runner - #9652

Open
pentreathm wants to merge 7 commits into
devfrom
chore/probe-windows-image-builder
Open

test: probe custom Windows GPU runner#9652
pentreathm wants to merge 7 commits into
devfrom
chore/probe-windows-image-builder

Conversation

@pentreathm

@pentreathm pentreathm commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

  • run a diagnostic-only probe on win-gpu-t4-explorer
  • verify Tesla T4 and WDDM
  • verify the persistent custom-image toolchain
  • verify the prewarmed NuGet and npm caches
  • avoid checkout, repository code, and secrets

Temporary workflow used to validate the new custom image before wiring the heavy automation suite.

@pentreathm
pentreathm requested a review from a team as a code owner August 6, 2026 17:28
@claude

This comment has been minimized.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

badge

New build in progress, come back later!

@pentreathm pentreathm changed the title ci: probe Windows GPU image builder test: probe custom Windows GPU runner Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🚦 CI Status

Build

Build skipped — no changes detected under Explorer/.

Lint

Waiting for lint to start…

Tests

Waiting for tests to start…

@claude

claude Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Security review — probe-windows-image-builder.yml (re-review after 4f519cbda)

  • Fetch base and diff the new head commit
  • Re-check workflow file (STEP W: W.1–W.10)
  • Re-check dependency surface (STEP 1–3)
  • Post verdict

View job run · Branch chore/probe-windows-image-builder

@claude

claude Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @pentreathm's task in 1m 46s —— View job


Security re-review after synchronizeprobe-windows-image-builder.yml

  • Fetch new commits and diff vs origin/dev
  • Re-run workflow security review (STEP W)
  • Re-check dependency surface (STEP 1–3)
  • Confirm which prior findings are now resolved
  • Post updated verdict

Scope

Still one added file, 128 lines, nothing else. Verified across all 7 commits (e42531dbd^..HEAD): .github/workflows/probe-windows-image-builder.yml is the only path touched. Packages/manifest.json, packages-lock.json, Assets/**, .asmdef files, and build/editor hooks are all untouched. STEP 1–3 (Unity dependency review) remains N/A — no shipped code, nothing reaches the desktop client. The new-dependency label fired on the workflow path.


Prior findings — all resolved

Prior finding Status in 3b8a91398 Evidence
HIGHpull_request trigger onto a custom runner Resolved The pull_request: block is gone. Triggers are now workflow_dispatch + push restricted to chore/probe-windows-image-builder (:3-9). No fork-controlled path onto the self-hosted runner; only users with push access can start it.
MEDIUMStop + trailing exit $LASTEXITCODE making the probe flaky Largely resolved Get-ComputerInfo is now a lone piped statement (:42-44), the fragile Win32_DesktopMonitor / Get-Volume -DriveLetter C calls are gone, and $global:LASTEXITCODE = 0 (:60) neutralizes the GPU step's exit code. One residue below.
LOW — unbounded recursive scans of both Program Files trees Resolved Replaced with an exact-path hashtable (:67-75). The only remaining -Recurse is scoped to C:\Tools\gh (:90), which is small.
LOWAdapterRAM misreporting a 16 GB T4 Resolved Dropped; nvidia-smi --query-gpu=name (:53) is now the source of truth.
LOWWin32_DesktopMonitor ambiguous on headless Resolved Replaced by an explicit \bWDDM\b assertion on nvidia-smi output (:56), which answers the actual question decisively.
LOW — no concurrency: block Resolved :13-15, cancel-in-progress: true, matching test.yml / visual-regression.yml convention.
LOWcontents: read broader than needed Resolved Now permissions: {} (:11).

STEP W re-run against the final tree: no secrets.*, no uses: at all, no actions/checkout, no pull_request_target, no LLM invocation, no artifact upload, no snapshot key. W.1–W.10 are N/A or satisfied. timeout-minutes: 10 (:21) bounds the hold on a scarce GPU runner.


Remaining — LOW, robustness not security

1. :96-103 — partial toolchain failures pass silently. Under $ErrorActionPreference = "Stop", a native command's non-zero exit does not throw; it only sets $LASTEXITCODE. GitHub appends exit $LASTEXITCODE, so the step's result is decided solely by the last invocation, & $expectedTools.mf --version (:103). If aws --version (:102) fails but mf succeeds, the step goes green and the probe reports a healthy toolchain it did not verify. Conversely, a non-zero mf --version fails the step with a bare Process completed with exit code N and no indication of which tool broke. Checking $LASTEXITCODE after each invocation — the pattern already used correctly at :50 and :54 — makes each tool's result explicit.

Fix this →

2. :492>&1 on a native command under Stop can terminate before the intended error message. In Windows PowerShell 5.1, merging a native command's stderr into the pipeline turns those lines into NativeCommandError records; with $ErrorActionPreference = "Stop" that becomes terminating. So if nvidia-smi writes any warning to stderr, the step dies at :49 with a PowerShell exception instead of the "nvidia-smi failed with exit code …" message at :50 that was written to explain it. A healthy nvidia-smi writes nothing to stderr, so this only bites in exactly the failure case the probe is meant to diagnose.

3. :53-54 — the GPU-name query has a null path and an unreliable exit code. If nvidia-smi --query-gpu=name emits no rows, Select-Object -First 1 yields $null and .Trim() throws a NullReferenceException before the guarded check at :55. Separately, Select-Object -First 1 tears down the upstream pipeline early, so $LASTEXITCODE at :54 may be stale from the :49 invocation rather than reflecting this one. Assigning to a variable first and testing for null/empty before .Trim() covers both.

4. :114-122 — exact-match env comparison is brittle. [Environment]::GetEnvironmentVariable(…, "Machine") returns the expanded string; a value stored as REG_EXPAND_SZ or with a trailing backslash fails -ne against the literal even though the cache is configured correctly. Not wrong today, just a likely source of a confusing red run later.

5. :80-88 — hashtable enumeration order is unspecified, so the summary table's row order varies between runs. Cosmetic.

6. Dead trigger after merge. The push filter names chore/probe-windows-image-builder (:7), which disappears on merge, and there is no pull_request trigger anymore — so post-merge this file is inert but lingers in dev. Since validation happens on the branch via push / workflow_dispatch anyway, not merging it is the cleanest outcome; otherwise please open a tracking issue for removal.


Verdict

The one blocking-class concern from my previous pass — fork PRs reaching the custom GPU runner through the pull_request trigger — is gone, and it was fixed by removing the trigger rather than by patching around it, which also moots the org-settings questions (runner-group public-repo access, fork-approval policy) that I couldn't read. permissions: {}, a bounded timeout, a concurrency group, no secrets, no checkout, no third-party actions, and no image snapshot: the attack surface is now essentially nil.

Everything left is probe reliability on a scarce GPU runner, not security. Finding 1 is the one I'd actually act on, since a silently-green toolchain check defeats the purpose of the probe.

DEPENDENCY_REVIEW: PASS

No files changed — I can't modify .github/workflows/ (GitHub App permissions don't allow workflow modifications), so any of the above would need to be applied by a human. See the FAQ for workarounds.
· Branch chore/probe-windows-image-builder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant