From 85305a2163fe428c5cb1aa9555a2f8e476ac8c67 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Tue, 28 Jul 2026 20:09:03 +0000 Subject: [PATCH] Stop four clean-machine checks from passing over a real failure Re-run `absent` after the install on the masked macOS legs. It only ran before, so an installer that quietly selected the Xcode CLT or installed a compiler left the leg green while every later source build could succeed, which is the one thing clean-machine-assert.sh says `absent` guards the whole run against. Fail the Windows simulation when py.exe can still start an interpreter. The launcher binary itself may stay, but Find-CompatiblePython probes `py` first (install.ps1:1130-1153), so an interpreter registered outside the two renamed toolcache directories gets reused and Python bootstrap is never exercised. Exempting `py` without ever running it left that unchecked. Propagate the WSL installer exit code. It was printed and discarded, and the CLI check does not compensate: install.sh links the `unsloth` shim (4174-4182) before it reports a failing studio/setup.sh (4219-4230), so a late setup failure leaves a shim whose --version succeeds. Run the bundled installer in the Linux desktop jobs. The launch step only proves the process stayed alive, and on a fresh home preflight reports not_installed and the app waits on the install screen, so both required rows passed after 90 seconds without ever touching the shipped install.sh. Locate the resource in the deb payload or the extracted AppImage, run it the way install.rs does, and require a managed venv that can import torch. --- .../workflows/clean-machine-install-ci.yml | 31 +++++++++++++++++-- .../desktop-app-clean-machine-ci.yml | 28 +++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/.github/workflows/clean-machine-install-ci.yml b/.github/workflows/clean-machine-install-ci.yml index bc78ae040d..bd37f9b1ce 100644 --- a/.github/workflows/clean-machine-install-ci.yml +++ b/.github/workflows/clean-machine-install-ci.yml @@ -183,8 +183,14 @@ jobs: run: | set -a; . ./clean-machine.env; set +a checks="nobuild" + # `absent` ran only BEFORE the install, so an installer that quietly + # selected the CLT or installed a compiler left the leg green while every + # later source build could succeed -- the exact behaviour the assert script + # says `absent` guards the whole run against. Re-run it after the install. + [ "${{ matrix.mode }}" = "mask" ] && checks="$checks absent" [ "${{ matrix.mode }}" = "trace" ] && checks="$checks notools" - bash .github/scripts/clean-machine-assert.sh $checks + UNSLOTH_CLEAN_ALLOW_WORKING='${{ matrix.allow_working }}' \ + bash .github/scripts/clean-machine-assert.sh $checks - name: Assert llama.cpp loads if: steps.install.outcome == 'success' @@ -438,7 +444,16 @@ jobs: # Piped, same shape as `curl ... | sh`, so an early exit still exposes the # broken pipe, but the script under test is this ref not production's. wsl -d unsloth-ci -u root -- sh -c 'cd /root && cat install.sh | sh' 2>&1 | Tee-Object -FilePath logs/wsl-install.log - Write-Host "installer exit: $LASTEXITCODE" + $installRc = $LASTEXITCODE + Write-Host "installer exit: $installRc" + # Printing the code discarded it. The CLI check in the next step does not + # compensate: install.sh links the `unsloth` shim (4174-4182) BEFORE it + # reports a failing studio/setup.sh (4219-4230), so a late setup failure + # leaves a shim whose --version succeeds and the whole job looked green. + if ($installRc -ne 0) { + Write-Host "::error::WSL installer exited $installRc" + exit $installRc + } - name: Did it detect WSL, and did it end up usable? if: always() @@ -608,6 +623,18 @@ jobs: Write-Host ("{0,-8} {1}" -f $t, $(if ($f) { $f.Source } else { 'ABSENT' })) if ($f -and $t -ne 'py') { $leaked += "$t -> $($f.Source)" } } + # The launcher binary may stay, but an interpreter it can still START is a + # leak: Find-CompatiblePython (install.ps1:1130-1153) probes `py` first, so + # any version registered outside the two renamed toolcache directories gets + # reused and Python bootstrap never runs. Exempting `py` without running it + # left that unchecked. + if (Get-Command py -ErrorAction SilentlyContinue) { + Write-Host "py -0p:"; & py -0p 2>&1 | ForEach-Object { Write-Host " $_" } + foreach ($v in '-3.11', '-3.12', '-3.13') { + $out = & py $v -c "import sys; print(sys.executable)" 2>&1 + if ($LASTEXITCODE -eq 0) { $leaked += "py $v -> $out" } + } + } # Printing alone could not fail, and the leg was green while not clean: run # 30365014702 logged `python ABSENT` then `Python 3.13 already installed` / # `Using CPython ... C:\hostedtoolcache\windows\Python\...`. diff --git a/.github/workflows/desktop-app-clean-machine-ci.yml b/.github/workflows/desktop-app-clean-machine-ci.yml index 621b3d1c68..b8ca0b1738 100644 --- a/.github/workflows/desktop-app-clean-machine-ci.yml +++ b/.github/workflows/desktop-app-clean-machine-ci.yml @@ -305,6 +305,34 @@ jobs: echo "BIN=$BIN" >> "$GITHUB_ENV" echo "binary: $BIN" + - name: Run the bundled installer, the path first launch takes + run: | + set -o pipefail + # The launch step below only proves the process stayed alive: on a fresh + # home preflight reports not_installed and the app sits on the install + # screen waiting for a click (use-tauri-backend.ts:252-254, + # startup-screen.tsx:388-389), so a bundle whose embedded install.sh is + # missing or broken passed both Linux rows. tauri.conf.json:56-59 ships + # install.sh as a bundle resource, so find it where the bundle put it and + # run it as install.rs does. + if [ "${{ matrix.kind }}" = "deb" ]; then + SH="$(dpkg -L "$(dpkg-deb -f dl/*.deb Package)" | grep -E '/install\.sh$' | head -1)" + else + (cd dl && "$(ls *.AppImage | head -1)" --appimage-extract >/dev/null) + SH="$(find dl/squashfs-root -name install.sh -type f | head -1)" + fi + [ -n "$SH" ] && [ -f "$SH" ] || { echo "::error::the bundle ships no install.sh resource"; exit 1; } + echo "bundled installer: $SH" + # --tauri rejects a custom studio home (install.sh:102-114), so drop the + # workspace-scoped override, and close stdin as install.rs does. + env -u UNSLOTH_STUDIO_HOME \ + bash "$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. + "$PY" -c "import torch; print('torch', torch.__version__)" + - name: Launch under Xvfb and prove it stays up run: | # Linux is the one platform where a hosted runner can give the app a real