Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
61a9719
CI: scope GITHUB_TOKEN permissions and unblock ~60 skipped tests
danielhanchen May 6, 2026
9f17de5
CI: add MLX CI workflow for the Studio dispatch matrix
danielhanchen May 6, 2026
107297d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 6, 2026
efcd2cc
ci(mlx): fix path filter that pointed at a non-existent file
danielhanchen May 6, 2026
8e19065
CI: split Studio GGUF CI into three focused jobs
danielhanchen May 6, 2026
bb1f4ed
CI: fix three regressions in the new Studio GGUF jobs
danielhanchen May 6, 2026
e10ff47
CI: add Studio Update CI + Studio UI CI workflows
danielhanchen May 6, 2026
2d9bf08
CI(ui): jump straight to /change-password to avoid /login auto-redire…
danielhanchen May 6, 2026
4b69262
CI(gguf,ui): unblock the Studio CI runs
danielhanchen May 6, 2026
76caf50
CI(gguf): consume SSE for tool calls, relax response_format test
danielhanchen May 6, 2026
2093c4a
CI(gguf,images): use a 64x64 PNG; stb_image rejects 4x4 as truncated
danielhanchen May 6, 2026
cee3247
CI: pass GH_TOKEN to install/update steps to dodge GitHub API rate li…
danielhanchen May 6, 2026
42ec259
CI(lint): turn the studio-backend ruff stub into a real Python gate
danielhanchen May 6, 2026
e774c41
CI(lint): split Python lint into a multi-language Lint CI workflow
danielhanchen May 6, 2026
467e01a
CI(lint): accept GNU long-form license headers (AGPL/LGPL/GPL)
danielhanchen May 6, 2026
de7fd06
CI: add codespell + shellcheck to Lint CI; add Security audit workflow
danielhanchen May 6, 2026
55ab255
CI: scan all unsloth deps + transitive closure, no install
danielhanchen May 6, 2026
f76e05a
CI(security): per-file audit, strip git+, pin setuptools in build env
danielhanchen May 6, 2026
fa2cd35
CI(security): shard scan_packages across 3 runners + dedupe per-shard
danielhanchen May 6, 2026
330e570
CI(security): consolidate pip-audit + npm audit + cargo audit into on…
danielhanchen May 6, 2026
1696a15
CI(security): catch Lightning, Shai-Hulud, npm hijack, design-flaw CVEs
danielhanchen May 6, 2026
f36f94f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 6, 2026
0879e72
CI(security): defense-in-depth additions across 7 axes
danielhanchen May 7, 2026
66103ab
CI(security): bump trivy + trufflehog to existing version tags
danielhanchen May 7, 2026
9261c3e
CI(security): trivy-action tags need leading `v` (0.36.0 -> v0.36.0)
danielhanchen May 7, 2026
f8eead1
CI(security): remove Trivy (it WAS the litellm attack vector)
danielhanchen May 7, 2026
12c6538
CI: SHA-pin every action; fix 4 bugs in advisory-audit
danielhanchen May 7, 2026
829405e
CI: rename + comprehensive Chat UI Tests (verified locally)
danielhanchen May 7, 2026
2f21961
CI(ui): drop nonexistent username locator (auth form is password-only)
danielhanchen May 7, 2026
22b6eb8
ci(mlx): add real Apple Silicon job on free macos-14 runner
danielhanchen May 7, 2026
c4c2b2a
ci(mlx): install unsloth-zoo from git main on the macOS job
danielhanchen May 7, 2026
4c85b82
ci(mlx): expand macOS install ladder to match the Linux dep set
danielhanchen May 7, 2026
30ddc7c
ci(mlx): version-pin every pip install, consolidate to one matrix job
danielhanchen May 7, 2026
9bb8dbc
CI(ui): split Playwright into tests/studio/playwright_chat_ui.py + co…
danielhanchen May 7, 2026
ff0d1bc
CI(security): random-generated passwords in every workflow (no hardco…
danielhanchen May 7, 2026
98d601b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
53ee9ce
ci(mlx): consolidate to single Mac M1 job with robust no-mlx spoof
danielhanchen May 7, 2026
50f257d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
c7e3989
ci(mlx): real MLX training + inference smoke test on Mac M1
danielhanchen May 7, 2026
5620926
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
388320d
ci(mlx): add LoRA + merged_16bit + GGUF export round-trip checks
danielhanchen May 7, 2026
a1b1412
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
246f54d
ci(mlx): cold-start LoRA / merged / GGUF reloads + per-phase metrics
danielhanchen May 7, 2026
779cc6c
CI(studio): always-upload artifacts + gate /api/system + path/health …
danielhanchen May 7, 2026
0e98886
CI(ui): STUDIO_UI_STRICT mode + theme cycle fix + Recents thread-matc…
danielhanchen May 7, 2026
29f2829
CI(studio): new Studio API & Auth Tests workflow + integration test
danielhanchen May 7, 2026
240efa8
CI(ui): add second Playwright job covering Compare/Recipes/Export/Stu…
danielhanchen May 7, 2026
3dfba6b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
1e20366
ci(mlx): fresh-process reloads + soft-skip GGUF on llama.cpp limitation
danielhanchen May 7, 2026
6c0f1d8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
0104c31
ci(mlx): expand LoRA targets to MLP + bump generation budget
danielhanchen May 7, 2026
3dadac5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
2a1b53b
CI(studio): fix 4 real failures surfaced by the new smoke jobs
danielhanchen May 7, 2026
11faba4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
41640d9
CI: add consolidated CPU tests (unsloth Bucket-A + unsloth_zoo@main +…
danielhanchen May 7, 2026
36f4cf4
CI(consolidated): spoof torch.cuda.is_available before bare unsloth_z…
danielhanchen May 7, 2026
5ff553f
CI(consolidated): drop `pip show … | head -3`, BrokenPipeError under …
danielhanchen May 7, 2026
60c0e4e
CI(consolidated): add protobuf, sentencepiece, triton to install ladder
danielhanchen May 7, 2026
2e6c17e
CI(ui): downgrade theme-cycle polarity check from strict to info
danielhanchen May 7, 2026
2e8c172
CI(consolidated): expand to runtime patch_* validation, TRL/MLP/hf_ut…
danielhanchen May 7, 2026
df81c35
CI(consolidated): set UNSLOTH_IS_PRESENT=1 so unsloth_zoo.__init__ ac…
danielhanchen May 7, 2026
4526641
ci(mlx): add Studio prebuilt llama.cpp + GGUF inference on Mac M1
danielhanchen May 7, 2026
44bd559
ci(mlx): pass --simple-policy when installing from ggml-org
danielhanchen May 7, 2026
9510bba
ci(mlx): use llama-server /completion for GGUF inference test
danielhanchen May 7, 2026
888355b
CI(consolidated): route bare unsloth_zoo imports through pytest shim …
danielhanchen May 7, 2026
b233937
ci(mac): add Mac Studio Update CI
danielhanchen May 7, 2026
3a72b50
ci(mac): add Mac Studio API/UI/GGUF CI workflows
danielhanchen May 7, 2026
99f4efe
CI(ui): make sidebar click_nav() locate via data-sidebar=menu-button …
danielhanchen May 7, 2026
2f2e637
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
b972214
CI(consolidated): matrix over (transformers, trl) combos + aggressive…
danielhanchen May 7, 2026
943c083
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
d03941e
ci(mac): make Mac smoke tests robust to Metal output drift
danielhanchen May 7, 2026
4aff561
CI(ui): nuke startViewTransition + force=True nav clicks (Chromium re…
danielhanchen May 7, 2026
e519ac5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
d1d8951
CI(consolidated): fix spoof recursion + per-step continue-on-error + …
danielhanchen May 7, 2026
851c73c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
4c70a9e
ci(mac): switch Mac GGUF jobs to UD-Q4_K_XL + bump UI turn timeout
danielhanchen May 7, 2026
c8b13b7
CI(ui-extra): use Enter to submit Compare composer + add aria-label
danielhanchen May 7, 2026
8a3e65a
CI(api-smoke): route status lines via os.write to dodge CodeQL false-…
danielhanchen May 7, 2026
6d801e5
fix: restore API and Help menu labels (#5310)
Imagineer99 May 6, 2026
63dab21
[studio]: Fix tool reasoning trace in UI (#5314)
CodeMan62 May 6, 2026
cce153c
ci(mac): tool-calling/json infra-only assertions + temp=0.2 anti-dege…
danielhanchen May 7, 2026
433cfa9
CI(consolidated): skip false-positive patches in runtime ledger; drop…
danielhanchen May 7, 2026
1ca86b2
ci(mac): handle llama-server vision crash + extra UI timing on macos-14
danielhanchen May 7, 2026
683ffcd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
ae8f54a
CI(ui): baseline-relative bubble count + hard-wait stop button + drop…
danielhanchen May 7, 2026
b79ae26
Merge main (with #5319 patch_* fixes) into PR #5312 branch so consoli…
danielhanchen May 7, 2026
39428fc
CI(consolidated): strict mode -- drop continue-on-error, tighten ledger
danielhanchen May 7, 2026
9617b9c
ci: trigger re-run on consolidated matrix after unsloth-zoo#630 merge
danielhanchen May 7, 2026
d08380d
CI(update-smoke): drop cache: 'pip' to avoid fatal post-step
danielhanchen May 7, 2026
d45a3b4
CI(consolidated): replace prebuilt-zip llama.cpp smoke with install_l…
danielhanchen May 7, 2026
10b498f
CI: rename consolidated workflow to "Core" with HF/TRL-pinned cell la…
danielhanchen May 7, 2026
ec9b25d
CI(Core): spoof torch.cuda before importing unsloth_zoo in llama.cpp …
danielhanchen May 7, 2026
a1a2087
ci(mlx): use mx.get_peak_memory with mx.metal.get_peak_memory fallback
danielhanchen May 7, 2026
20e06ac
CI(Core): add compiler-cache coverage (synthetic invariants + real-cl…
danielhanchen May 7, 2026
99c42d3
CI(Core): add TRL trainer + Config auto-discovery sweep
danielhanchen May 7, 2026
6556192
CI(Core): drop higher_precision_softmax idempotency assertion (tracke…
danielhanchen May 7, 2026
b11219b
CI(Core): restore higher_precision_softmax idempotency assertion (uns…
danielhanchen May 7, 2026
f8860ad
CI(Core): filter TRL trainer/config sweep to actual submodules only
danielhanchen May 7, 2026
6573de3
CI(ui-extra): downgrade Compare bubble assertions to runtime_warn
danielhanchen May 7, 2026
048491b
CI(ui): filter benign pageerrors before gating on the count
danielhanchen May 7, 2026
f26cb19
ci(mac): downgrade Mac extra-UI brittle assertions to info-only
danielhanchen May 7, 2026
5d4217b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
11bec73
ci: trigger re-run on consolidated matrix after unsloth-zoo#630 merge
danielhanchen May 7, 2026
5181c71
ci(mac): trim max_tokens + timeouts so tool-calling/json fit in 25min
danielhanchen May 7, 2026
7855571
CI(Core): all-models compile sweep + dynamic TRL trainer/experimental…
danielhanchen May 7, 2026
a26efef
CI(Core): MoE per-family coverage + GRPO patches + grouped_gemm AST
danielhanchen May 7, 2026
694d88c
CI(Core): expand KNOWN_BROKEN_COMPILE with 7 latest-transformers fail…
danielhanchen May 7, 2026
ebf6dd2
ci(mac): pin Playwright <1.58 to dodge Node 24 pipeTransport JSON crash
danielhanchen May 7, 2026
00e863e
CI(windows): four Windows Studio CI workflows on free windows-latest …
danielhanchen May 7, 2026
13f79e4
fix(install): pin click+shellingham in no-torch-runtime.txt
danielhanchen May 7, 2026
5f2511c
CI(windows): force UTF-8 stdio so hf download / Studio CLI don't cras…
danielhanchen May 7, 2026
8bc52ff
fix(install): pin full typer dep tree (annotated-doc, rich, etc.)
danielhanchen May 7, 2026
d35bf6a
ci(mac): retry Playwright JSON crash + GGUF detect retry + MLX is_ggu…
danielhanchen May 7, 2026
c6d4495
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
c84ff19
fix(install): add pydantic_core + annotated-types to no-torch-runtime…
danielhanchen May 7, 2026
f813403
CI(windows): patch Studio venv with full typer/pydantic dep trees
danielhanchen May 7, 2026
54cd084
CI(windows): use *>&1 to capture PS Information stream (Write-Host) i…
danielhanchen May 7, 2026
a810e8f
Merge remote-tracking branch 'origin/main' into ci/workflow-permissio…
danielhanchen May 7, 2026
fdf7f94
ci(mac): single-process Chromium + JSON.parse try/catch in pipeTransport
danielhanchen May 7, 2026
9bfd4bc
fix(install): retry GitHub API 403 with Retry-After / X-RateLimit-Reset
danielhanchen May 7, 2026
ba805bf
CI(windows): filesystem-based prebuilt assertion + GITHUB_PATH shim e…
danielhanchen May 7, 2026
bfb5c28
CI(notebooks): cross-repo validator for unslothai/notebooks
danielhanchen May 7, 2026
0114207
CI(notebooks): mark lint step continue-on-error until backlog clears
danielhanchen May 7, 2026
9707b80
CI(vllm): GRPO + fast_inference vLLM compat across 0.9 .. 0.15
danielhanchen May 7, 2026
5042b38
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 7, 2026
a65b730
CI(notebooks): tolerate upstream drift + add nbformat to api-introspect
danielhanchen May 7, 2026
1b92a8b
ci(mac): make Playwright screenshots best-effort + 90s timeout
danielhanchen May 7, 2026
0566df2
CI(notebooks): add triton to api-introspect install (unsloth import n…
danielhanchen May 7, 2026
1e61265
ci(mac): bump Playwright timeouts 30s -> 60s for slow macos-14 runner
danielhanchen May 7, 2026
86e31c9
CI(notebooks): api-introspect job needs Pillow + torchvision + safete…
danielhanchen May 7, 2026
f3e541d
CI(notebooks): api-introspect installs unsloth from local checkout
danielhanchen May 7, 2026
9bf0c6f
ci(mac): wait_for_load_state before change-password form + drop pre-f…
danielhanchen May 7, 2026
0823562
Merge branch 'main' into ci/workflow-permissions-and-fewer-skips
danielhanchen May 7, 2026
47432b0
cli(windows): capture setup.ps1 Write-Host output via -Command + *>&1
danielhanchen May 8, 2026
e25e3c5
ci(windows): make --single-process Chromium darwin-only in playwright…
danielhanchen May 8, 2026
fa3840c
scripts: harden github_blob_to_raw against substring URL spoofing
danielhanchen May 8, 2026
112690d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
f2c2b3f
studio/setup.ps1: mirror step/substep output to [Console]::Out for pi…
danielhanchen May 8, 2026
2453134
cli(windows): pass sys.stdio handles explicitly to powershell.exe
danielhanchen May 8, 2026
e46860b
ci(windows update): use jq instead of windows-python to read health.json
danielhanchen May 8, 2026
d179701
ci(ui): bound the Recents-click step + structural data-testid selector
danielhanchen May 8, 2026
d65f8b1
ci(windows): cache Studio venv + llama.cpp prebuilt + frontend dist
danielhanchen May 8, 2026
6a37af2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
e1345d5
Revert: drop Windows cache steps -- measured neutral / negative
danielhanchen May 8, 2026
091a80b
ci(core): factor llama.cpp build out of consolidated matrix into its …
danielhanchen May 8, 2026
7878c65
ci(inference): trim tool-calling test wall-time roughly 50%
danielhanchen May 8, 2026
2843e2a
ci(windows): pre-upgrade npm to 11 + Defender exclusions for ~/.unslo…
danielhanchen May 8, 2026
4e1f1e9
ci(windows): do not pre-create dist/node_modules before Defender excl…
danielhanchen May 8, 2026
1b71061
ci(inference): port main's --local-dir gguf-cache pattern to tool-cal…
danielhanchen May 8, 2026
e3f9727
Revert tool-calling trim on Linux + Windows; keep Mac
danielhanchen May 8, 2026
fec4ee0
ci(mlx): unpin unsloth_zoo from PR #627 branch now that it is merged
danielhanchen May 8, 2026
81534dd
ci(consolidated): prune electra from KNOWN_BROKEN_COMPILE post-zoo#632
danielhanchen May 8, 2026
420f588
ci(notebooks): diff Colab oracle against committed snapshots
danielhanchen May 8, 2026
3274f72
ci(studio-mac): retry composer.wait_for after change-password redirect
danielhanchen May 8, 2026
61fdf83
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
6ec6ca3
ci: add cross-version compat canary for vLLM, TRL, PEFT, ST, bnb
danielhanchen May 8, 2026
a41a315
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
00f3e32
Merge branch 'main' into ci/workflow-permissions-and-fewer-skips
danielhanchen May 8, 2026
f0a4a5a
ci(studio-mac): retry whole change-password form on re-render race
danielhanchen May 8, 2026
c876296
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
b205ddd
ci(version-compat): expand TRL coverage + add transformers + PEFT extras
danielhanchen May 9, 2026
200822c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2026
a975d58
ci(version-compat): expand bnb matrix + add extended zoo-import smoke
danielhanchen May 9, 2026
30870d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2026
7ceb67d
ci: fix 3 failures on a975d588 (torchcodec, repo-cpu auto-discovery, …
danielhanchen May 9, 2026
a2bc48c
ci(playwright): extract shared robustness helpers + harden against CI…
danielhanchen May 9, 2026
16c4f65
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 9, 2026
960e68d
ci: bump actions/* org pins to latest
danielhanchen May 11, 2026
4b8e886
Merge branch 'main' into ci/workflow-permissions-and-fewer-skips
danielhanchen May 11, 2026
cb59709
ci(version-compat): broaden paths gate from 3 files to unsloth/**
danielhanchen May 11, 2026
5506d8c
Merge branch 'main' into ci/workflow-permissions-and-fewer-skips
danielhanchen May 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,25 @@ updates:
groups:
npm-oxc-validator:
patterns: ["*"]

# pip + cargo so security advisories on Python deps + the Tauri shell
# auto-generate PRs alongside the github-actions / bun / npm updates.
# Grouped weekly so we don't get one PR per dep; security advisories
# bypass the group and open immediately.
- package-ecosystem: "pip"
directory: "/"
Comment on lines +32 to +33
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point Dependabot at Studio requirement manifests

With the new pip entry scoped to directory: "/", Dependabot only scans the root Python manifests; I checked the repo and the Studio runtime requirements live under studio/backend/requirements/*.txt, outside that directory. That means Python security advisories for Studio dependencies will not auto-generate PRs despite the comment saying this covers Python deps, so add a directories entry or separate pip updates for the Studio requirements paths.

Useful? React with 👍 / 👎.

Comment on lines +32 to +33
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add Dependabot entries for Studio requirements

With the pip updater scoped only to directory: "/", Dependabot will monitor the root Python manifest but not the separate Studio backend requirement manifests under studio/backend/requirements/. In practice, security advisory PRs for packages pinned only in those files will not be opened even though this block says Python advisories are covered; add a pip update entry for the Studio requirements directory (and any nested manifest directory that should be monitored).

Useful? React with 👍 / 👎.

schedule:
interval: "weekly"
open-pull-requests-limit: 5
groups:
python:
patterns: ["*"]

- package-ecosystem: "cargo"
directory: "/studio/src-tauri"
schedule:
interval: "weekly"
groups:
cargo-tauri:
patterns: ["*"]
...
2,144 changes: 2,144 additions & 0 deletions .github/workflows/consolidated-tests-ci.yml

Large diffs are not rendered by default.

319 changes: 319 additions & 0 deletions .github/workflows/lint-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.

# Whole-repo, multi-language source-lint gate. Runs on every PR
# (no path filter) because each step is sub-second to a few seconds
# and together they catch a class of breakage the focused build
# workflows would miss:
#
# - Python syntax + ruff + leftover debugger calls (across 350+
# committed .py files, not just studio/backend).
# - Shell `bash -n` parse for every committed *.sh.
# - `yaml.safe_load` and `json.loads` round-trip for every
# committed YAML / JSON config.
#
# TypeScript and Rust are NOT duplicated here on purpose:
# - Studio Frontend CI runs `npm run typecheck` (= `tsc --noEmit`)
# and `npm run build` (vite/swc) on every studio/frontend/**
# change, which is a full TS AST + type check.
# - Studio Tauri CI runs `tauri build --debug --no-bundle` on
# every studio/src-tauri/** or studio/frontend/** change, which
# compiles the Rust crate (= cargo check + cargo build).
# Each is a stricter check than a parse-only step would be, so a
# fast-fail duplicate here would only burn cache; the dedicated
# workflows already block merges on Rust / TS regressions.

name: Lint CI

on:
pull_request:
push:
branches: [main, pip]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
source-lint:
name: Source lint (Python + shell + YAML + JSON + safety nets)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run lint syntax gate on all supported Python minors

This workflow hard-pins the syntax gate to Python 3.12, so it can pass while code still fails on supported runtimes declared in pyproject.toml (>=3.9). I rechecked this repo and python3.10 -m py_compile unsloth/kernels/moe/tests/common.py currently fails with a syntax error, which means this new hard gate will miss real user-facing breakage on 3.10/3.11. Matrix this compile step across supported minors (or narrow support) so CI actually enforces the advertised compatibility range.

Useful? React with 👍 / 👎.

cache: 'pip'

# Pin ruff to match .pre-commit-config.yaml so a CI-only ruff
# bump cannot disagree with what pre-commit accepted.
# codespell is pinned for the same reason: a reviewer should
# never see a typo report appear and disappear depending on
# which codespell version the runner happened to install.
- run: pip install 'ruff==0.15.12' 'pyyaml>=6' 'codespell>=2.3,<3'

- name: Linux deps for shellcheck
run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends shellcheck

- name: Python AST/syntax check (every committed .py must compile)
# python -m compileall uses the same parser the interpreter
# uses, so anything broken here would also crash at
# `import X` on a user's machine. Sub-second across 350+
# files. Hard gate.
run: |
python -m compileall -q -j 0 \
unsloth unsloth_cli studio tests cli.py unsloth-cli.py
Comment on lines +69 to +70
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include scripts in Python lint inputs

This new workflow is described as a whole-repo Python syntax/ruff gate, but both hard-gating commands omit the top-level scripts/ directory even though this commit adds critical Python entrypoints there (notebook_validator.py, notebook_to_python.py, scan_packages.py). For PRs that change only scripts not covered by the narrower notebook/security workflow path filters, syntax errors or undefined names in those shipped scripts can pass Lint CI green; add scripts to the compileall and ruff input lists.

Useful? React with 👍 / 👎.


- name: Python ruff check (whole repo)
# The narrow rule set in pyproject.toml [tool.ruff.lint]
# selects E9 / F63 / F7 / F82 -- syntax errors, broken
# comparisons, undefined names. The whole repo passes today,
# so this is a hard gate.
run: |
ruff check unsloth unsloth_cli studio tests cli.py unsloth-cli.py

- name: No leftover debugger / pdb / breakpoint calls
# Catches the "I'll just stick a breakpoint() here" mistake
# before it ships. AST-based so commented-out debugger
# markers don't false-positive (a bare grep would; there
# are three commented `# breakpoint()` markers in
# unsloth/models/rl* today). Sub-second.
run: |
python <<'PY'
import ast, pathlib, sys

SKIP_PARTS = {".venv", "venv", "build", "dist", ".git",
"unsloth_compiled_cache", "node_modules",
"unsloth.egg-info"}

bad = []
scanned = 0
for path in sorted(pathlib.Path(".").rglob("*.py")):
if any(part in SKIP_PARTS for part in path.parts):
continue
scanned += 1
try:
tree = ast.parse(path.read_text(encoding="utf-8", errors="replace"))
except SyntaxError:
continue # compileall step above already failed this
for node in ast.walk(tree):
if not isinstance(node, ast.Call):
continue
fn = node.func
if isinstance(fn, ast.Name) and fn.id == "breakpoint":
bad.append((path, node.lineno, "breakpoint()"))
elif (isinstance(fn, ast.Attribute) and fn.attr == "set_trace"
and isinstance(fn.value, ast.Name)
and fn.value.id in {"pdb", "ipdb"}):
bad.append((path, node.lineno, f"{fn.value.id}.set_trace()"))

if bad:
for path, lineno, what in bad:
print(f"::error file={path},line={lineno}::leftover {what} -- remove before merging")
sys.exit(1)
print(f"no leftover debugger calls (scanned {scanned} files)")
PY

- name: License-header drift (informational; whole repo)
# Three header families are accepted across the repo:
# 1. SPDX one-liner: `# SPDX-License-Identifier: ...`
# Used across studio/ (AGPL-3.0-only) and a few new
# files elsewhere.
# 2. Apache-2.0 long form, marker phrase
# "Licensed under the Apache License". Used across
# unsloth/ and unsloth_cli/.
# 3. GNU long form, marker phrase "General Public License".
# That single substring covers GPL, LGPL ("GNU Lesser
# General Public License") and AGPL ("GNU Affero
# General Public License") preambles, all three of
# which appear in unsloth/kernels/* (LGPL/AGPL) without
# the SPDX line.
# Empty files (mainly empty __init__.py) are skipped.
# Surfaced as a warning; cleaning up the actual misses is a
# follow-up PR, not a CI fix.
continue-on-error: true
run: |
python <<'PY'
import pathlib

ACCEPTED = (
"SPDX-License-Identifier", # any SPDX line
"Licensed under the Apache License", # Apache-2.0 long form
"General Public License", # GPL / LGPL / AGPL long form
)
SKIP_PARTS = {".venv", "venv", "build", "dist", ".git",
"unsloth_compiled_cache", "node_modules",
"unsloth.egg-info"}

studio_missing = []
other_missing = []
for path in sorted(pathlib.Path(".").rglob("*.py")):
if any(part in SKIP_PARTS for part in path.parts):
continue
text = path.read_text(encoding="utf-8", errors="replace")
if not text.strip():
continue # empty __init__.py etc.
head = "\n".join(text.splitlines()[:25])
if any(marker in head for marker in ACCEPTED):
continue
if "studio" in path.parts:
studio_missing.append(path)
else:
other_missing.append(path)

total = len(studio_missing) + len(other_missing)
if total == 0:
print("every committed .py has a recognised license header")
else:
print(f"::warning::{total} Python files have no recognised license "
f"header (SPDX / Apache-2.0 / GNU long form): "
f"studio={len(studio_missing)}, other={len(other_missing)}")
for path in (studio_missing + other_missing)[:30]:
print(f" {path}")
if total > 30:
print(f" ... and {total - 30} more")
PY

- name: Shell scripts parse cleanly (`bash -n`)
# Same idea as Python's compileall: parse-only check that
# every committed *.sh would not blow up at `bash script.sh`
# invocation time on a release box. tests/sh/ is the largest
# cluster (the install.sh shape tests).
run: |
shopt -s globstar
fail=0
for f in $(git ls-files '*.sh'); do
if ! bash -n "$f"; then
echo "::error file=$f::shell parse error"
fail=1
fi
done
if [ "$fail" -ne 0 ]; then
exit 1
fi
n=$(git ls-files '*.sh' | wc -l)
echo "$n shell scripts parse cleanly"

- name: YAML files parse cleanly (yaml.safe_load)
# Catches truncated workflow files, broken indents in
# dependabot.yml / pre-commit configs, etc. Includes
# .github/workflows/*.yml so a typo in the file we just
# added shows up immediately.
run: |
python <<'PY'
import pathlib, sys, yaml

SKIP_PARTS = {".venv", "venv", "build", "dist", ".git",
"node_modules", "unsloth_compiled_cache",
"unsloth.egg-info"}

bad = []
scanned = 0
for path in sorted(list(pathlib.Path(".").rglob("*.yml"))
+ list(pathlib.Path(".").rglob("*.yaml"))):
if any(part in SKIP_PARTS for part in path.parts):
continue
scanned += 1
try:
with path.open("r", encoding="utf-8") as fh:
list(yaml.safe_load_all(fh))
except Exception as exc:
bad.append((path, exc))

if bad:
for path, exc in bad:
print(f"::error file={path}::YAML parse failed: {exc}")
sys.exit(1)
print(f"{scanned} YAML files parse cleanly")
PY

- name: JSON files parse cleanly (json.loads)
# Catches malformed package.json, biome.json, etc. Skips:
# - huge npm/bun lockfiles (machine-generated, slow to
# parse, no value).
# - tsconfig*.json: TypeScript convention is JSONC (JSON
# with `/* ... */` comments), which standard json.loads
# rejects. Strip-and-validate would need json5 or a
# hand-rolled comment scrubber for marginal value, since
# `tsc --noEmit` already validates these in Frontend CI.
run: |
python <<'PY'
import fnmatch, json, pathlib, sys

SKIP_PARTS = {".venv", "venv", "build", "dist", ".git",
"node_modules", "unsloth_compiled_cache",
"unsloth.egg-info"}
SKIP_NAMES = {"package-lock.json", "bun.lock"}
SKIP_PATTERNS = ("tsconfig*.json",)

bad = []
scanned = 0
for path in sorted(pathlib.Path(".").rglob("*.json")):
if any(part in SKIP_PARTS for part in path.parts):
continue
if path.name in SKIP_NAMES:
continue
if any(fnmatch.fnmatch(path.name, pat) for pat in SKIP_PATTERNS):
continue
scanned += 1
try:
json.loads(path.read_text(encoding="utf-8"))
except Exception as exc:
bad.append((path, exc))

if bad:
for path, exc in bad:
print(f"::error file={path}::JSON parse failed: {exc}")
sys.exit(1)
print(f"{scanned} JSON files parse cleanly")
PY

- name: codespell typo check (informational)
# Catches typos in code, comments, and docs across the repo.
# Skips lockfiles, generated assets, binary artefacts, and
# the LICENSE files (US/UK spelling drift in legal text is
# not ours to second-guess). The ignore-words-list pulls
# out short identifiers + valid technical terms that
# codespell's default dictionary would otherwise flag
# (e.g. `ans` as a math-quiz variable name in
# tests/utils/aime_eval.py, `parm`/`parms` in PyTorch
# nn.Module idioms). Non-blocking until the surfaced typos
# are fixed; drop continue-on-error after the cleanup.
continue-on-error: true
run: |
codespell \
--skip='*.lock,*.lockb,*.json,*.svg,*.png,*.jpg,*.jpeg,*.gif,*.ico,*.woff*,*.ttf,*.eot,*.zip,*.gz,*.gguf,*.safetensors,*.bin,node_modules,.git,build,dist,unsloth_compiled_cache,unsloth.egg-info,target,studio/frontend/dist,*.pyc,*-licenses.txt,LICENSE*' \
--ignore-words-list='ans,bu,hel,fo,te,ot,hist,ned,sav,recurser,datas,nin,parm,parms,checkin,nd,fr,inout,donot,uint' \
--quiet-level=2

- name: shellcheck on committed *.sh (informational)
# Goes beyond `bash -n` (which only parses): catches subtle
# shell bugs like unquoted variable expansions, useless
# `cat`, command substitutions inside `[[`, etc. The
# install/setup scripts are critical-path so the signal is
# worth surfacing. Non-blocking until install.sh's
# hand-rolled patterns get cleaned up; drop continue-on-error
# afterwards.
continue-on-error: true
run: |
# Exclude SC1090 ("source not followable") -- legitimate
# for installer scripts that source files at runtime
# paths shellcheck cannot resolve statically.
# SC2034 ("variable assigned but never used") fires on
# the export-only assignment idiom we use in install.sh.
shellcheck -e SC1090,SC2034 $(git ls-files '*.sh')

- name: ruff format drift (informational)
# The canonical formatter is scripts/run_ruff_format.py
# = ruff format + scripts/enforce_kwargs_spacing.py, so plain
# `ruff format --check` reports the kwarg-spacing diff as
# drift. Surface the count for visibility but keep
# non-blocking until the custom pipeline is wired in here.
continue-on-error: true
run: |
ruff format --check unsloth unsloth_cli studio tests cli.py unsloth-cli.py
Loading
Loading