Make the Windows and Linux clean-machine legs honest

The Windows scrub only touched PATH, so the legs were green while not clean: run
30365014702 logged "python ABSENT" and then "Python 3.13 already installed"
with uv resolving C:\hostedtoolcache\windows\Python\3.13.14\arm64\python.exe.
py.exe lives in C:\Windows and uv discovers interpreters itself, so take the
toolcache off disk and fail when tooling survives, instead of only printing it.

The Linux desktop legs never stripped anything, and the tauri.log step was all
|| true so it could not fail. Run the bundled installer the way install.rs does,
with --tauri alone, and assert torch: passing --no-torch skipped the slowest
half of first launch and let the venv check pass over it.

Pin the WSL rootfs to a dated build; current/ is a rolling alias and the digest
next to it is fixed.
This commit is contained in:
danielhanchen 2026-07-28 15:13:48 +00:00
commit eea0433f0e
2 changed files with 35 additions and 3 deletions

View file

@ -404,7 +404,7 @@ jobs:
run: |
# WSL2 is present on windows-2022+ runner images; only a distro is missing.
wsl --set-default-version 2
$url = 'https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz'
$url = 'https://cloud-images.ubuntu.com/wsl/releases/24.04/20240423/ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz'
$expected = '2a790896740b14d637dbdc583cce1ba081ac53b9e9cdb46dc09a2f73abbd9934'
New-Item -ItemType Directory -Force -Path wsl-dist, logs | Out-Null
Invoke-WebRequest -Uri $url -OutFile wsl-dist/rootfs.tar.gz -UseBasicParsing -TimeoutSec 900
@ -542,6 +542,17 @@ jobs:
-Value "@`"$($wingetCmd.Source)`" %*"
$kept = @($shim) + $kept
}
# Take the toolcache Python off disk, not just off PATH. py.exe lives in
# C:\Windows (which must stay) and uv does its own interpreter discovery, so
# both reach the toolcache no matter what PATH says -- which is how a leg
# printing `python ABSENT` still installed with the runner's 3.13.14.
foreach ($tc in @("$env:AGENT_TOOLSDIRECTORY\Python", 'C:\hostedtoolcache\windows\Python')) {
if ($tc -and (Test-Path $tc)) {
try { Rename-Item -LiteralPath $tc -NewName 'Python.masked' -ErrorAction Stop
Write-Host "masked toolcache python: $tc" }
catch { Write-Host "::error::could not mask $tc ($($_.Exception.Message)); the leg would not be clean"; exit 1 }
}
}
$newPath = ($kept -join ';')
"PATH=$newPath" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
# install.ps1 calls Refresh-SessionPath (defined install.ps1:318-337, called at
@ -570,9 +581,20 @@ jobs:
- name: Verify the simulation took effect
shell: pwsh
run: |
foreach ($t in 'python','git','cmake','cl') {
$leaked = @()
# `py` too: the launcher lives in C:\Windows, which the scrub keeps, and it
# finds the toolcache Python the scrub just removed from PATH.
foreach ($t in 'python','py','git','cmake','cl') {
$f = Get-Command $t -ErrorAction SilentlyContinue
Write-Host ("{0,-8} {1}" -f $t, $(if ($f) { $f.Source } else { 'ABSENT' }))
if ($f -and $t -ne 'py') { $leaked += "$t -> $($f.Source)" }
}
# Printing alone could not fail, and the leg was green while not clean:
# run 30365014702 logged `python ABSENT` and then `Python 3.13 already
# installed` / `Using CPython ... C:\hostedtoolcache\windows\Python\...`.
if ($leaked) {
Write-Host "::error::developer tooling survived the scrub: $($leaked -join '; ')"
exit 1
}
$winget = Get-Command winget -ErrorAction SilentlyContinue
Write-Host ("winget {0}" -f $(if ($winget) { $winget.Source } else { 'ABSENT' }))

View file

@ -166,11 +166,15 @@ jobs:
# does: --tauri, stdin closed, no tty. --tauri rejects a custom studio
# home (install.sh:102-114), so drop the workspace-scoped override.
env -u UNSLOTH_STUDIO_HOME \
bash "$APP/Contents/Resources/install.sh" --tauri --no-torch \
bash "$APP/Contents/Resources/install.sh" --tauri \
< /dev/null 2>&1 | tee logs/bundled-install.log
PY="$HOME/.unsloth/studio/unsloth_studio/bin/python"
[ -x "$PY" ] || { echo "::error::bundled installer left no venv at $PY"; exit 1; }
"$PY" -V
# install.rs passes only --tauri, so torch is part of first launch. Dropping
# --no-torch here and asserting torch keeps the venv check from passing over
# a bundle whose only failure is the torch install.
"$PY" -c "import torch; print('torch', torch.__version__)"
- name: Launch and prove it stays up
run: |
@ -204,7 +208,13 @@ jobs:
tail -60 "$f"
# The two fields the bug report turned on.
grep -E "disposition=|can_auto_repair=|Xcode Command Line|ModuleNotFoundError" "$f" || true
found=1
done
# Everything above is `|| true`, so on its own this step could not fail while
# the header sells the tauri.log disposition as an acceptance criterion.
# setup_logging (src-tauri/src/main.rs:50-67) opens tauri.log unconditionally
# at process start, so no log at all means the binary never got that far.
[ "${found:-0}" = "1" ] || { echo "::error::the app wrote no tauri.log; it never reached setup_logging"; exit 1; }
- name: Restore the runner
if: always()