CI(windows): filesystem-based prebuilt assertion + GITHUB_PATH shim export

Two real Windows-specific issues from the latest round:

1. The prebuilt-llama-installed asserter relied on grepping
   logs/install.log for "prebuilt installed and validated". That
   marker is emitted by setup.ps1 (a child process spawned by
   install.ps1 via `& $UnslothExe studio setup`) -- the child's
   Write-Host stream does NOT come back through the parent's
   Tee-Object pipeline regardless of how aggressively we redirect
   (*>&1, 2>&1, etc.). The marker lands on the live GitHub Actions
   console but never on disk. Switch to a filesystem-based check:

     * UNSLOTH_PREBUILT_INFO.json must exist at
       ~/.unsloth/llama.cpp/UNSLOTH_PREBUILT_INFO.json (setup.ps1
       writes this from the prebuilt response payload).
     * llama-server.exe must exist at
       ~/.unsloth/llama.cpp/build/bin/Release/llama-server.exe.

   Both must be true; their JSON content is also dumped to the CI
   log for debugging.

2. install.ps1 adds $StudioHome\bin (where the unsloth.exe shim
   lives) to the User PATH via a Windows registry write. That
   registry update doesn't propagate to the running Git Bash
   session, so the very next step (`unsloth studio reset-password`)
   hits "unsloth: command not found" and exits 127. Re-export
   ~/.unsloth/studio/bin to $GITHUB_PATH (Windows-style via
   cygpath) so every subsequent step in the same job sees it.

Both fixes are mechanical and apply to all 4 Windows workflows
(6 jobs total: 1 ui + 1 update + 1 api + 3 inference).
This commit is contained in:
Daniel Han 2026-05-07 11:24:12 +00:00
commit ba805bf501
4 changed files with 182 additions and 18 deletions

View file

@ -92,11 +92,42 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Filesystem-based check (setup.ps1's stream output isn't
# captured back through this parent step's pipeline; see
# studio-windows-ui-smoke.yml for full explanation).
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO."
ls -la "$LLAMA_DIR" || true
exit 1
fi
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN."
ls -la "$LLAMA_DIR/build/bin" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
# install.ps1's User-PATH update doesn't propagate to a
# running Git Bash session; export the shim dir so the
# next `unsloth ...` invocation finds it.
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
- name: Patch Studio venv with full typer / pydantic dep trees
# Belt-and-suspenders: install.ps1's --no-deps install of

View file

@ -102,11 +102,37 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Filesystem check; setup.ps1's stream output isn't captured.
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO."
ls -la "$LLAMA_DIR" || true
exit 1
fi
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN."
ls -la "$LLAMA_DIR/build/bin" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
- name: Patch Studio venv with full typer / pydantic dep trees
# Belt-and-suspenders: install.ps1's --no-deps install of
@ -341,11 +367,37 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Filesystem check; setup.ps1's stream output isn't captured.
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO."
ls -la "$LLAMA_DIR" || true
exit 1
fi
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN."
ls -la "$LLAMA_DIR/build/bin" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
- name: Patch Studio venv with full typer / pydantic dep trees
# Belt-and-suspenders: install.ps1's --no-deps install of
@ -671,11 +723,37 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Filesystem check; setup.ps1's stream output isn't captured.
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO."
ls -la "$LLAMA_DIR" || true
exit 1
fi
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN."
ls -la "$LLAMA_DIR/build/bin" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
- name: Patch Studio venv with full typer / pydantic dep trees
# Belt-and-suspenders: install.ps1's --no-deps install of

View file

@ -110,21 +110,55 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Windows install must take the prebuilt path. The CPU
# asset name is llama-bNNNN-bin-win-cpu-x64.zip on
# windows-latest (no GPU). Source-build fallback here
# is a Studio bug -- we ship Windows prebuilts.
# install.ps1's setup.ps1 child writes "prebuilt installed
# and validated" to its own console host -- that output
# does NOT come back through this parent step's stdout
# pipeline (no matter how aggressively we redirect: *>&1,
# tee, etc.). Verify the install via the filesystem
# instead. setup.ps1 writes UNSLOTH_PREBUILT_INFO.json
# next to the install dir on success, and lays the
# binaries under build/bin/Release/ on Windows.
STUDIO_HOME=~/.unsloth/studio
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
# Source-build fallback grep stays as a fast bail-out.
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if ! grep -qE "prebuilt installed and validated|prebuilt up to date and validated|bin-win-cpu-x64|bin-win-cuda-" logs/install.log; then
echo "::error::no Windows prebuilt llama.cpp marker in install.log."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO; setup.ps1 didn't install the prebuilt."
ls -la "$LLAMA_DIR" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp"
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN; prebuilt extraction incomplete."
ls -la "$LLAMA_DIR/build/bin" || true
ls -la "$LLAMA_DIR/build/bin/Release" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
# install.ps1 puts unsloth.exe at $StudioHome\bin\unsloth.exe
# and adds that dir to the User PATH via the Windows registry.
# Registry-level PATH updates don't propagate to a running
# Git Bash session, so the next step's `unsloth ...` invocation
# would hit "command not found". Re-export the shim dir to
# GITHUB_PATH so every subsequent step in this job sees it.
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
# GITHUB_PATH wants Windows-style paths; convert via cygpath.
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
echo "Added Studio shim dir to PATH: $(cygpath -w "$SHIM_DIR")"
- name: Patch Studio venv with full typer / pydantic dep trees
# Belt-and-suspenders: install.ps1's --no-deps install of

View file

@ -87,17 +87,38 @@ jobs:
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
run: |
# Filesystem-based check (setup.ps1's stream output isn't
# captured back through the parent pipeline).
LLAMA_DIR=~/.unsloth/llama.cpp
INFO="$LLAMA_DIR/UNSLOTH_PREBUILT_INFO.json"
BIN="$LLAMA_DIR/build/bin/Release/llama-server.exe"
if grep -q "falling back to source build" logs/install.log; then
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows. Studio must install the prebuilt llama-bNNNN-bin-win-cpu-x64 on Windows."
echo "::error::install.ps1 fell back to source-build llama.cpp on Windows."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
exit 1
fi
if ! grep -qE "prebuilt installed and validated|prebuilt up to date and validated|bin-win-cpu-x64|bin-win-cuda-" logs/install.log; then
echo "::error::no Windows prebuilt llama.cpp marker in install.log."
grep -E "llama-prebuilt|llama.cpp" logs/install.log | tail -60
if [ ! -f "$INFO" ]; then
echo "::error::no UNSLOTH_PREBUILT_INFO.json at $INFO."
ls -la "$LLAMA_DIR" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp"
if [ ! -f "$BIN" ]; then
echo "::error::no llama-server.exe at $BIN."
ls -la "$LLAMA_DIR/build/bin" || true
exit 1
fi
echo "install.ps1 installed the Windows prebuilt llama.cpp:"
cat "$INFO"
- name: Add Studio shim to GITHUB_PATH
run: |
SHIM_DIR=~/.unsloth/studio/bin
if [ ! -f "$SHIM_DIR/unsloth.exe" ]; then
echo "::error::unsloth.exe shim not found at $SHIM_DIR"
ls -la ~/.unsloth/studio/ || true
exit 1
fi
cygpath -w "$SHIM_DIR" >> "$GITHUB_PATH"
- name: Patch Studio venv with full typer / pydantic dep trees
# install.ps1 runs `uv pip install --no-deps -r