mirror of
https://github.com/unslothai/unsloth.git
synced 2026-07-09 15:58:41 +00:00
Bumps the actions group with 11 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `4.2.2` | `7.0.0` | | [actions/setup-python](https://github.com/actions/setup-python) | `6.2.0` | `6.3.0` | | [actions/cache/restore](https://github.com/actions/cache) | `5.0.5` | `6.1.0` | | [actions/cache/save](https://github.com/actions/cache) | `5.0.5` | `6.1.0` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4.6.1` | `7.0.1` | | [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.19.1` | `2.19.4` | | [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.1` | `2.4.3` | | [github/codeql-action](https://github.com/github/codeql-action) | `3` | `4.36.3` | | [tauri-apps/tauri-action](https://github.com/tauri-apps/tauri-action) | `0.6.2` | `1.0.0` | | [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) | `3.95.3` | `3.95.8` | | [actions/stale](https://github.com/actions/stale) | `10.2.0` | `10.3.0` | Updates `actions/checkout` from 4.2.2 to 7.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.2.2...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) Updates `actions/setup-python` from 6.2.0 to 6.3.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v6.2.0...ece7cb06caefa5fff74198d8649806c4678c61a1) Updates `actions/cache/restore` from 5.0.5 to 6.1.0 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](27d5ce7f10...55cc834586) Updates `actions/cache/save` from 5.0.5 to 6.1.0 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](27d5ce7f10...55cc834586) Updates `actions/upload-artifact` from 4.6.1 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.6.1...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) Updates `step-security/harden-runner` from 2.19.1 to 2.19.4 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](a5ad31d6a1...9af89fc715) Updates `ossf/scorecard-action` from 2.4.1 to 2.4.3 - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](f49aabe0b5...4eaacf0543) Updates `github/codeql-action` from 3 to 4.36.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4.36.3) Updates `tauri-apps/tauri-action` from 0.6.2 to 1.0.0 - [Release notes](https://github.com/tauri-apps/tauri-action/releases) - [Changelog](https://github.com/tauri-apps/tauri-action/blob/dev/CHANGELOG.md) - [Commits](84b9d35b5f...1deb371b0c) Updates `trufflesecurity/trufflehog` from 3.95.3 to 3.95.8 - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](37b77001d0...00155c9dc5) Updates `actions/stale` from 10.2.0 to 10.3.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](b5d41d4e1d...eb5cf3af3a) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: actions/cache/restore dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/cache/save dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: step-security/harden-runner dependency-version: 2.19.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: github/codeql-action dependency-version: 4.36.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: tauri-apps/tauri-action dependency-version: 1.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/stale dependency-version: 10.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com>
406 lines
18 KiB
YAML
406 lines
18 KiB
YAML
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
|
|
|
|
# Windows counterpart to studio-ui-smoke.yml / studio-mac-ui-smoke.yml.
|
|
# Same Playwright + Chromium end-to-end chat UI flow + extra UI flow,
|
|
# but on the FREE windows-latest runner so we catch Windows-specific
|
|
# regressions in the install path (install.ps1), the Studio CLI's
|
|
# Windows process-management branches, and the llama.cpp prebuilt's
|
|
# Windows HTTP layer.
|
|
|
|
name: Windows Studio UI CI
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'studio/**'
|
|
- 'unsloth/**'
|
|
- 'unsloth_cli/**'
|
|
- 'install.ps1'
|
|
- 'pyproject.toml'
|
|
- 'tests/studio/**'
|
|
- '.github/workflows/studio-windows-ui-smoke.yml'
|
|
push:
|
|
branches: [main, pip]
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
ui-smoke:
|
|
name: Chat UI Tests
|
|
runs-on: windows-latest
|
|
timeout-minutes: 45
|
|
# Default every step's shell to Git Bash. windows-latest's default
|
|
# shell is pwsh; without this each curl / heredoc / `kill $PID`
|
|
# step would need its own `shell: bash`. Steps that genuinely
|
|
# need PowerShell (install.ps1 invocation) override per-step.
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
env:
|
|
GGUF_REPO: unsloth/gemma-3-270m-it-GGUF
|
|
GGUF_VARIANT: UD-Q4_K_XL
|
|
GGUF_FILE: gemma-3-270m-it-UD-Q4_K_XL.gguf
|
|
STUDIO_PORT: '18896'
|
|
HF_HOME: ${{ github.workspace }}/hf-cache
|
|
# Force UTF-8 for stdio so Python tools (hf download, Studio
|
|
# CLI, etc.) can print Unicode characters like the success
|
|
# checkmark "✓". Windows defaults to cp1252 / charmap and
|
|
# any tool that prints "OK ✓" hits a UnicodeEncodeError.
|
|
PYTHONIOENCODING: utf-8
|
|
PYTHONUTF8: '1'
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: '22'
|
|
# No `cache: 'npm'`. setup-node's npm cache restore silently
|
|
# aborts the entire job on Windows runners when the npm cache
|
|
# path (`C:\npm\cache` per `npm config get cache`) doesn't yet
|
|
# exist on a fresh runner -- the step exits without an error
|
|
# message and every following step gets skipped. See
|
|
# npm/cli#7308. The frontend `npm ci` is fast enough without
|
|
# the cache that the reliability gain is worth the ~30s.
|
|
|
|
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
with:
|
|
python-version: '3.12'
|
|
# No `cache: 'pip'`. install.ps1 / setup.ps1 use uv and
|
|
# never populate ~/.cache/pip; setup-python's post-step
|
|
# then fatal-errors with "Cache folder path is retrieved
|
|
# for pip but doesn't exist on disk".
|
|
|
|
- name: Restore HF_HOME for ${{ env.GGUF_REPO }}
|
|
id: cache-hf
|
|
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
continue-on-error: true
|
|
with:
|
|
path: hf-cache
|
|
key: ${{ runner.os }}-hf-${{ env.GGUF_REPO }}-${{ env.GGUF_VARIANT }}-v2
|
|
|
|
- name: Prime HF_HOME with the GGUF
|
|
id: prime-hf
|
|
if: steps.cache-hf.outputs.cache-hit != 'true' || steps.cache-hf.outcome != 'success'
|
|
env:
|
|
# Withheld on PR: this step runs checked-out PR code; public GGUF still downloads.
|
|
HF_TOKEN: ${{ github.event_name != 'pull_request' && secrets.HF_TOKEN || '' }}
|
|
run: |
|
|
python -m pip install --upgrade huggingface_hub
|
|
mkdir -p hf-cache
|
|
bash .github/scripts/hf-download-with-retry.sh "$GGUF_REPO" "$GGUF_FILE"
|
|
bash .github/scripts/hf-download-with-retry.sh ggml-org/models tinyllamas/stories260K.gguf
|
|
|
|
- name: Save HF_HOME for ${{ env.GGUF_REPO }}
|
|
if: always() && steps.prime-hf.outcome == 'success'
|
|
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: hf-cache
|
|
key: ${{ runner.os }}-hf-${{ env.GGUF_REPO }}-${{ env.GGUF_VARIANT }}-v2
|
|
|
|
- name: Pre-install Windows tweaks (npm 11 + Defender exclusions)
|
|
shell: pwsh
|
|
# See studio-windows-update-smoke.yml for the full rationale.
|
|
# tl;dr: setup.ps1 needs npm >=11 to skip a 35 s winget Node
|
|
# reinstall, and Defender's real-time scan dominates the
|
|
# frontend / uv-pip-extract steps.
|
|
run: |
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
Write-Host "npm version before upgrade: $(npm -v)"
|
|
npm install -g 'npm@^11' 2>&1 | Out-Host
|
|
Write-Host "npm version after upgrade: $(npm -v)"
|
|
# NOTE: do NOT pre-create these directories. See
|
|
# studio-windows-update-smoke.yml for the full rationale --
|
|
# creating an empty studio/frontend/dist trips setup.ps1's
|
|
# mtime-based staleness check into "frontend up to date, skip
|
|
# rebuild" and Studio boots with an empty dist directory.
|
|
# Add-MpPreference accepts paths that do not yet exist.
|
|
foreach ($p in @(
|
|
"$env:USERPROFILE\.unsloth",
|
|
"$env:USERPROFILE\AppData\Local\uv",
|
|
"$env:GITHUB_WORKSPACE\studio\frontend\node_modules",
|
|
"$env:GITHUB_WORKSPACE\studio\frontend\dist"
|
|
)) {
|
|
try {
|
|
Add-MpPreference -ExclusionPath $p -ErrorAction Stop
|
|
Write-Host "Defender exclusion added: $p"
|
|
} catch {
|
|
Write-Host "Defender exclusion skipped ($($_.Exception.Message)): $p"
|
|
}
|
|
}
|
|
|
|
- name: Seed a legacy launch-studio.vbs (upgrade-cleanup check)
|
|
# Simulate a pre-hardening install so the post-install assertion below
|
|
# proves the installer DELETES an existing launch-studio.vbs (the exact
|
|
# Kaspersky-flagged file), not merely stops generating it.
|
|
shell: pwsh
|
|
run: |
|
|
$appDir = Join-Path $env:LOCALAPPDATA 'Unsloth Studio'
|
|
New-Item -ItemType Directory -Force -Path $appDir | Out-Null
|
|
Set-Content -LiteralPath (Join-Path $appDir 'launch-studio.vbs') -Value 'WScript.Echo "legacy"' -Encoding Unicode
|
|
Write-Host "seeded legacy launch-studio.vbs at $appDir"
|
|
|
|
- name: Install Studio (--local, --no-torch)
|
|
# install.ps1 is the supported Windows installer. install.sh
|
|
# has no Windows branch (apt-get / brew calls). The PS1
|
|
# script's `Install-UnslothStudio @args` line at the bottom
|
|
# forwards `--local --no-torch` correctly.
|
|
shell: pwsh
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
# Withheld on PR: this step runs checked-out PR code; public GGUF still downloads.
|
|
HF_TOKEN: ${{ github.event_name != 'pull_request' && secrets.HF_TOKEN || '' }}
|
|
run: |
|
|
New-Item -ItemType Directory -Force -Path logs | Out-Null
|
|
# *>&1 redirects ALL PowerShell streams (stdout, stderr,
|
|
# warning, verbose, debug, information) into the success
|
|
# stream so Tee-Object captures everything. install.ps1
|
|
# and setup.ps1 emit step/substep markers via Write-Host
|
|
# which lands on the Information stream (PS 5+); without
|
|
# the wildcard redirect, those markers (including
|
|
# "prebuilt installed and validated") never reach
|
|
# logs/install.log and the post-step grep asserter fails.
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
& ./install.ps1 --local --no-torch *>&1 | Tee-Object -FilePath logs/install.log
|
|
|
|
- name: Assert install.ps1 used the Windows llama.cpp prebuilt
|
|
run: |
|
|
# 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."
|
|
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; setup.ps1 didn't install the prebuilt."
|
|
ls -la "$LLAMA_DIR" || true
|
|
exit 1
|
|
fi
|
|
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: Assert Studio launcher chain (no VBS, hidden PowerShell shortcut)
|
|
# The shortcut launch path is otherwise untested here (the steps below
|
|
# boot `unsloth studio` directly). Guard against re-introducing the VBS
|
|
# that tripped Kaspersky HEUR:Trojan.VBS.Agent.gen and against the .lnk
|
|
# pointing anywhere other than hidden PowerShell over launch-studio.ps1.
|
|
shell: pwsh
|
|
run: |
|
|
$appDir = Join-Path $env:LOCALAPPDATA 'Unsloth Studio'
|
|
if (Test-Path -LiteralPath (Join-Path $appDir 'launch-studio.vbs')) {
|
|
throw "regression: launch-studio.vbs exists (the Kaspersky VBS-FP shape)"
|
|
}
|
|
if (-not (Test-Path -LiteralPath (Join-Path $appDir 'launch-studio.ps1'))) {
|
|
throw "missing launch-studio.ps1 in $appDir"
|
|
}
|
|
$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Unsloth Studio.lnk'
|
|
if (-not (Test-Path -LiteralPath $lnk)) {
|
|
$lnk = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs\Unsloth Studio.lnk'
|
|
}
|
|
if (-not (Test-Path -LiteralPath $lnk)) { throw "no Unsloth Studio.lnk on Desktop or Start Menu" }
|
|
$sc = (New-Object -ComObject WScript.Shell).CreateShortcut($lnk)
|
|
Write-Host "shortcut target: $($sc.TargetPath)"
|
|
Write-Host "shortcut args: $($sc.Arguments)"
|
|
if ($sc.TargetPath -match 'wscript\.exe$') { throw "shortcut still targets wscript.exe (VBS host)" }
|
|
if ($sc.TargetPath -notmatch 'powershell\.exe$') { throw "unexpected shortcut target: $($sc.TargetPath)" }
|
|
if ($sc.Arguments -notmatch '-WindowStyle Hidden') {
|
|
throw "shortcut must launch windowless (-WindowStyle Hidden)"
|
|
}
|
|
Write-Host "launcher chain OK (no VBS; hidden powershell over launch-studio.ps1)"
|
|
|
|
- name: Launch Studio via the shortcut and assert health
|
|
# Run the exact command the .lnk stores (hidden PowerShell over
|
|
# launch-studio.ps1) and confirm it brings the backend up. This is the
|
|
# only step that proves the shortcut launch is not silently broken.
|
|
# Default port range is 8888-8908; the later UI tests use 18896/18897, so
|
|
# there is no conflict, and we tear this server down before they boot.
|
|
shell: pwsh
|
|
run: |
|
|
$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Unsloth Studio.lnk'
|
|
if (-not (Test-Path -LiteralPath $lnk)) {
|
|
$lnk = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs\Unsloth Studio.lnk'
|
|
}
|
|
$sc = (New-Object -ComObject WScript.Shell).CreateShortcut($lnk)
|
|
Write-Host "launching: $($sc.TargetPath) $($sc.Arguments)"
|
|
Start-Process -FilePath $sc.TargetPath -ArgumentList $sc.Arguments -WorkingDirectory $sc.WorkingDirectory
|
|
$foundPort = 0
|
|
foreach ($i in 1..180) {
|
|
foreach ($port in 8888..8908) {
|
|
try {
|
|
$r = Invoke-RestMethod -Uri "http://127.0.0.1:$port/api/health" -TimeoutSec 1
|
|
if ($r.status -eq 'healthy' -and $r.service -eq 'Unsloth UI Backend') { $foundPort = $port; break }
|
|
} catch {}
|
|
}
|
|
if ($foundPort) { break }
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
# Tear down the shortcut-launched server before the main UI tests boot.
|
|
try {
|
|
$owner = (Get-NetTCPConnection -LocalPort $foundPort -State Listen -ErrorAction Stop | Select-Object -First 1).OwningProcess
|
|
if ($owner) { taskkill /PID $owner /T /F 2>$null | Out-Null }
|
|
} catch {}
|
|
if (-not $foundPort) { throw "Studio did not become healthy when launched via the shortcut" }
|
|
Write-Host "Studio healthy on port $foundPort (launched via the shortcut)"
|
|
|
|
- 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: Install Playwright + Chromium
|
|
# No --with-deps on Windows: that flag installs Linux apt
|
|
# packages. windows-latest ships the system frameworks
|
|
# Chromium needs (Edge / WebView2) already.
|
|
run: |
|
|
python -m pip install 'playwright>=1.45'
|
|
python -m playwright install chromium
|
|
|
|
- name: Reset auth + boot Studio
|
|
run: |
|
|
unsloth studio reset-password
|
|
mkdir -p logs
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p "$STUDIO_PORT" \
|
|
> logs/studio.log 2>&1 &
|
|
echo "STUDIO_PID=$!" >> "$GITHUB_ENV"
|
|
|
|
- name: Wait for /api/health
|
|
run: |
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:${STUDIO_PORT}/api/health" > /tmp/health.json; then
|
|
jq -e '.status == "healthy"' /tmp/health.json && break
|
|
fi
|
|
sleep 1
|
|
done
|
|
jq -e '.status == "healthy"' /tmp/health.json
|
|
|
|
- name: Pass bootstrap password to the Playwright step
|
|
run: |
|
|
OLD=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
NEW="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
NEW2="CIUi-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$OLD"
|
|
echo "::add-mask::$NEW"
|
|
echo "::add-mask::$NEW2"
|
|
echo "STUDIO_OLD_PW=$OLD" >> "$GITHUB_ENV"
|
|
echo "STUDIO_NEW_PW=$NEW" >> "$GITHUB_ENV"
|
|
echo "STUDIO_NEW2_PW=$NEW2" >> "$GITHUB_ENV"
|
|
|
|
- name: Drive the chat UI with Playwright
|
|
env:
|
|
BASE_URL: http://127.0.0.1:18896
|
|
PW_ART_DIR: logs/playwright
|
|
STUDIO_UI_STRICT: '1'
|
|
# windows-latest free runner is 4 vCPU / 16 GB; gemma-3-
|
|
# 270m turn latency under llama-server's CPU backend can
|
|
# crowd the 180s default (slower than ubuntu-latest on
|
|
# the same model). Keep the same generous budget the Mac
|
|
# job uses.
|
|
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
|
run: |
|
|
mkdir -p logs/playwright
|
|
python tests/studio/playwright_chat_ui.py
|
|
|
|
- name: Stop Studio (chat-ui ends with Shutdown click; this is belt-and-suspenders)
|
|
if: always()
|
|
run: |
|
|
kill "${STUDIO_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
|
|
- name: Reset auth + boot Studio for extra UI tests (port 18897)
|
|
run: |
|
|
unsloth studio reset-password
|
|
mkdir -p logs
|
|
UNSLOTH_API_ONLY=1 unsloth studio -H 127.0.0.1 -p 18897 \
|
|
> logs/studio_extra.log 2>&1 &
|
|
echo "STUDIO_EXTRA_PID=$!" >> "$GITHUB_ENV"
|
|
|
|
- name: Wait for /api/health on 18897
|
|
run: |
|
|
for i in $(seq 1 180); do
|
|
if curl -fs "http://127.0.0.1:18897/api/health" > /tmp/health2.json; then
|
|
jq -e '.status == "healthy"' /tmp/health2.json && break
|
|
fi
|
|
sleep 1
|
|
done
|
|
jq -e '.status == "healthy"' /tmp/health2.json
|
|
|
|
- name: Pass bootstrap pw for extra UI test
|
|
run: |
|
|
OLD=$(cat ~/.unsloth/studio/auth/.bootstrap_password)
|
|
NEW="CIUiExtra-$(python -c 'import secrets; print(secrets.token_urlsafe(16))')"
|
|
echo "::add-mask::$OLD"
|
|
echo "::add-mask::$NEW"
|
|
echo "STUDIO_EXTRA_OLD_PW=$OLD" >> "$GITHUB_ENV"
|
|
echo "STUDIO_EXTRA_NEW_PW=$NEW" >> "$GITHUB_ENV"
|
|
|
|
- name: Drive Compare/Recipes/Export/Studio/Settings with Playwright
|
|
env:
|
|
BASE_URL: http://127.0.0.1:18897
|
|
STUDIO_OLD_PW: ${{ env.STUDIO_EXTRA_OLD_PW }}
|
|
STUDIO_NEW_PW: ${{ env.STUDIO_EXTRA_NEW_PW }}
|
|
PW_ART_DIR: logs/playwright_extra
|
|
STUDIO_UI_STRICT: '1'
|
|
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
|
GGUF_REPO: ${{ env.GGUF_REPO }}
|
|
GGUF_VARIANT: ${{ env.GGUF_VARIANT }}
|
|
run: |
|
|
mkdir -p logs/playwright_extra
|
|
python tests/studio/playwright_extra_ui.py
|
|
|
|
- name: Stop second Studio
|
|
if: always()
|
|
run: |
|
|
kill "${STUDIO_EXTRA_PID}" 2>/dev/null || true
|
|
sleep 2
|
|
|
|
- name: Upload Playwright artifacts
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: windows-studio-ui-smoke-artifacts
|
|
path: |
|
|
logs/studio.log
|
|
logs/studio_extra.log
|
|
logs/install.log
|
|
logs/playwright
|
|
logs/playwright_extra
|
|
retention-days: 7
|