Skip to content

Commit 9653c5c

Browse files
committed
Pin patched MLX-LM on self-hosted E2E runners
1 parent 321f271 commit 9653c5c

4 files changed

Lines changed: 90 additions & 30 deletions

File tree

.github/workflows/e2e-matrix.yml

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ on:
1010
- "tests/fixtures/build_e2e_matrix.py"
1111
- "tests/fixtures/tokenizers/**"
1212
- "tests/fixtures/parquet/**"
13+
- "scripts/install_self_hosted_e2e_python.sh"
1314
- ".github/workflows/e2e-matrix.yml"
1415
pull_request:
1516
branches: [main]
1617
paths:
1718
- "cppmega_v4/**"
1819
- "vbgui/**"
1920
- "tests/fixtures/build_e2e_matrix.py"
21+
- "scripts/install_self_hosted_e2e_python.sh"
22+
- ".github/workflows/e2e-matrix.yml"
2023
schedule:
2124
# Nightly full run — includes the mini-train matrix on macOS.
2225
- cron: "0 4 * * *"
@@ -26,6 +29,10 @@ concurrency:
2629
group: e2e-matrix-${{ github.ref }}
2730
cancel-in-progress: true
2831

32+
env:
33+
CPPMEGA_MLX_LM_CHECKOUT: /Volumes/external/sources/mlx-lm
34+
CPPMEGA_MLX_LM_COMMIT: 8618587943181787d33bac4468d3088e80202b3f
35+
2936
jobs:
3037
# On every push/PR: smoke matrix (912 cells). The backend imports MLX, so
3138
# this runs on the repository's persistent Apple Silicon runner.
@@ -62,15 +69,7 @@ jobs:
6269
echo "VBGUI_E2E_BACKEND_PORT=$((port_base + port_offset))" >> "$GITHUB_ENV"
6370
echo "VBGUI_E2E_FRONTEND_PORT=$((port_base + 10 + port_offset))" >> "$GITHUB_ENV"
6471
- name: Python deps
65-
run: |
66-
"$VBGUI_E2E_PYTHON" -m pip install --disable-pip-version-check \
67-
-e ".[gui,parquet,widget]"
68-
"$VBGUI_E2E_PYTHON" - <<'PY'
69-
from cppmega_mlx.training.native_optim import status
70-
native_status = status()
71-
if not native_status.get("available", False):
72-
raise RuntimeError(native_status.get("reason", "native optimizer extension unavailable"))
73-
PY
72+
run: scripts/install_self_hosted_e2e_python.sh
7473
- name: Generate fixtures
7574
run: |
7675
"$VBGUI_E2E_PYTHON" tests/fixtures/build_e2e_matrix.py
@@ -134,15 +133,7 @@ jobs:
134133
port_offset=8
135134
echo "VBGUI_E2E_BACKEND_PORT=$((port_base + port_offset))" >> "$GITHUB_ENV"
136135
echo "VBGUI_E2E_FRONTEND_PORT=$((port_base + 10 + port_offset))" >> "$GITHUB_ENV"
137-
- run: |
138-
"$VBGUI_E2E_PYTHON" -m pip install --disable-pip-version-check \
139-
-e ".[gui,parquet,widget]"
140-
"$VBGUI_E2E_PYTHON" - <<'PY'
141-
from cppmega_mlx.training.native_optim import status
142-
native_status = status()
143-
if not native_status.get("available", False):
144-
raise RuntimeError(native_status.get("reason", "native optimizer extension unavailable"))
145-
PY
136+
- run: scripts/install_self_hosted_e2e_python.sh
146137
- run: |
147138
"$VBGUI_E2E_PYTHON" tests/fixtures/build_e2e_matrix.py
148139
- working-directory: vbgui
@@ -201,15 +192,7 @@ jobs:
201192
port_offset=9
202193
echo "VBGUI_E2E_BACKEND_PORT=$((port_base + port_offset))" >> "$GITHUB_ENV"
203194
echo "VBGUI_E2E_FRONTEND_PORT=$((port_base + 10 + port_offset))" >> "$GITHUB_ENV"
204-
- run: |
205-
"$VBGUI_E2E_PYTHON" -m pip install --disable-pip-version-check \
206-
-e ".[gui,parquet,widget]"
207-
"$VBGUI_E2E_PYTHON" - <<'PY'
208-
from cppmega_mlx.training.native_optim import status
209-
native_status = status()
210-
if not native_status.get("available", False):
211-
raise RuntimeError(native_status.get("reason", "native optimizer extension unavailable"))
212-
PY
195+
- run: scripts/install_self_hosted_e2e_python.sh
213196
- run: |
214197
"$VBGUI_E2E_PYTHON" tests/fixtures/build_e2e_matrix.py
215198
- working-directory: vbgui
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${VBGUI_E2E_PYTHON:?VBGUI_E2E_PYTHON must name the isolated runner Python}"
5+
: "${CPPMEGA_MLX_LM_CHECKOUT:?CPPMEGA_MLX_LM_CHECKOUT must name the patched mlx-lm checkout}"
6+
: "${CPPMEGA_MLX_LM_COMMIT:?CPPMEGA_MLX_LM_COMMIT must pin the patched mlx-lm checkout}"
7+
8+
repo_root="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}"
9+
actual_commit="$(git -C "$CPPMEGA_MLX_LM_CHECKOUT" rev-parse HEAD)"
10+
if [[ "$actual_commit" != "$CPPMEGA_MLX_LM_COMMIT" ]]; then
11+
printf 'patched mlx-lm checkout mismatch: expected=%s actual=%s\n' \
12+
"$CPPMEGA_MLX_LM_COMMIT" "$actual_commit" >&2
13+
exit 1
14+
fi
15+
git -C "$CPPMEGA_MLX_LM_CHECKOUT" diff --quiet
16+
git -C "$CPPMEGA_MLX_LM_CHECKOUT" diff --cached --quiet
17+
18+
"$VBGUI_E2E_PYTHON" -m pip install --disable-pip-version-check \
19+
-e "$CPPMEGA_MLX_LM_CHECKOUT"
20+
"$VBGUI_E2E_PYTHON" -m pip install --disable-pip-version-check \
21+
-e "$repo_root[gui,parquet,widget]"
22+
23+
"$VBGUI_E2E_PYTHON" - "$CPPMEGA_MLX_LM_CHECKOUT" <<'PY'
24+
from pathlib import Path
25+
import sys
26+
27+
from mlx_lm.models import (
28+
bailing_hybrid,
29+
deepseek_v4,
30+
gemma4_assistant,
31+
mistral4,
32+
nemotron_h,
33+
turbo_cache,
34+
)
35+
36+
from cppmega_mlx.training.native_optim import status
37+
38+
39+
checkout = Path(sys.argv[1]).resolve()
40+
for module in (
41+
bailing_hybrid,
42+
deepseek_v4,
43+
gemma4_assistant,
44+
mistral4,
45+
nemotron_h,
46+
turbo_cache,
47+
):
48+
module_path = Path(module.__file__).resolve()
49+
if not module_path.is_relative_to(checkout):
50+
raise RuntimeError(
51+
f"mlx-lm module {module.__name__} came from {module_path}, "
52+
f"not pinned checkout {checkout}"
53+
)
54+
55+
native_status = status()
56+
if not native_status.get("available", False):
57+
raise RuntimeError(
58+
native_status.get("reason", "native optimizer extension unavailable")
59+
)
60+
PY

tests/test_workflow_runner_policy.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,27 @@ def test_macos_e2e_uses_an_isolated_job_venv() -> None:
8888
assert workflow.count('echo "PYTHONPATH=" >> "$GITHUB_ENV"') == 3
8989
assert workflow.count('echo "PYTHONNOUSERSITE=1" >> "$GITHUB_ENV"') == 3
9090
assert "--no-build-isolation" not in workflow
91-
assert workflow.count('-e ".[gui,parquet,widget]"') == 3
91+
assert workflow.count("run: scripts/install_self_hosted_e2e_python.sh") == 3
9292
assert workflow.count('echo "VBGUI_E2E_PYTHON=$job_venv/bin/python"') == 3
9393
assert workflow.count('rm -rf "$VBGUI_E2E_VENV"') == 3
94-
assert workflow.count("native optimizer extension unavailable") == 3
94+
95+
installer = (
96+
REPO_ROOT / "scripts" / "install_self_hosted_e2e_python.sh"
97+
).read_text(encoding="utf-8")
98+
assert '-e "$CPPMEGA_MLX_LM_CHECKOUT"' in installer
99+
assert '-e "$repo_root[gui,parquet,widget]"' in installer
100+
assert 'rev-parse HEAD' in installer
101+
assert 'diff --cached --quiet' in installer
102+
assert "native optimizer extension unavailable" in installer
103+
for module in (
104+
"bailing_hybrid",
105+
"deepseek_v4",
106+
"gemma4_assistant",
107+
"mistral4",
108+
"nemotron_h",
109+
"turbo_cache",
110+
):
111+
assert module in installer
95112

96113

97114
def test_macos_e2e_jobs_use_run_scoped_ports() -> None:

tests/v4/test_e2e_matrix_report.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_workflow_uploads_artifacts():
4747

4848
def test_workflow_runs_mini_train_only_on_macos_nightly():
4949
text = WORKFLOW.read_text()
50-
assert "macos-latest" in text
50+
assert "runs-on: [self-hosted, macOS, ARM64, cppmega-mlx-macos]" in text
5151
assert "github.event_name == 'schedule'" in text
5252

5353

0 commit comments

Comments
 (0)