Skip to content

Commit d480705

Browse files
committed
a66602
1 parent f14b8a6 commit d480705

4 files changed

Lines changed: 184 additions & 75 deletions

File tree

.github/workflows/ci-gpu.yml

Lines changed: 178 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,216 @@
1-
name: CI • GPU (CUDA)
1+
name: CI (Windows Self-Hosted + GPU)
22

33
on:
4-
workflow_dispatch:
54
push:
65
branches: [ main ]
76
paths:
8-
- ".github/workflows/**"
7+
- "**.py"
8+
- "pyproject.toml"
9+
- "requirements*.txt"
10+
- ".github/workflows/ci-gpu.yml"
911
- "app/**"
1012
- "tests/**"
1113
pull_request:
12-
paths:
13-
- ".github/workflows/**"
14-
- "app/**"
15-
- "tests/**"
14+
branches: [ main ]
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: read
1619

1720
concurrency:
18-
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
21+
group: ci-${{ github.ref }}-${{ github.workflow }}
1922
cancel-in-progress: true
2023

21-
permissions:
22-
contents: read
24+
defaults:
25+
run:
26+
shell: pwsh
2327

2428
env:
25-
PYTHONUNBUFFERED: "1"
2629
PIP_DISABLE_PIP_VERSION_CHECK: "1"
27-
APP_RELOAD: "false"
28-
APP_DEVICE: "cuda:0"
29-
HF_HOME: ${{ github.workspace }}/models_cache/huggingface
30-
TORCH_HOME: ${{ github.workspace }}/models_cache/torch
31-
TRANSFORMERS_CACHE: ${{ github.workspace }}/models_cache/huggingface/hub
30+
PIP_NO_PYTHON_VERSION_WARNING: "1"
31+
PYTHONDONTWRITEBYTECODE: "1"
3232

3333
jobs:
34-
windows-gpu:
35-
name: Windows GPU • py${{ matrix.python }}
36-
runs-on: [self-hosted, windows, gpu, cuda]
37-
timeout-minutes: 45
38-
strategy:
39-
fail-fast: false
40-
matrix:
41-
python: ['3.12']
34+
lint:
35+
name: Lint (ruff/flake + basic checks)
36+
runs-on: [self-hosted, Windows, X64]
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@v4
40+
41+
- name: Bootstrap cache/env vars
42+
id: boot
43+
run: |
44+
$cacheDir = Join-Path $env:RUNNER_TEMP 'pip-cache'
45+
"cache_dir=$cacheDir" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
46+
"os=$env:RUNNER_OS" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
47+
48+
- name: Set up Python
49+
uses: actions/setup-python@v5
50+
with:
51+
python-version: "3.12"
52+
53+
- name: Cache pip
54+
uses: actions/cache@v4
55+
with:
56+
path: ${{ steps.boot.outputs.cache_dir }}
57+
key: pip-${{ steps.boot.outputs.os }}-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }}
58+
restore-keys: |
59+
pip-${{ steps.boot.outputs.os }}-
4260
61+
- name: Install tooling
62+
run: |
63+
python -m pip install -U pip wheel setuptools
64+
python -m pip install ruff flake8
65+
66+
- name: Ruff check
67+
run: ruff check .
68+
69+
- name: Flake8
70+
run: flake8 .
71+
72+
tests-cpu:
73+
name: Tests (CPU)
74+
runs-on: [self-hosted, Windows, X64]
75+
needs: [lint]
4376
steps:
44-
- uses: actions/checkout@v4
77+
- name: Checkout
78+
uses: actions/checkout@v4
79+
80+
- name: Bootstrap cache/env vars
81+
id: boot
82+
run: |
83+
$cacheDir = Join-Path $env:RUNNER_TEMP 'pip-cache'
84+
"cache_dir=$cacheDir" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
85+
"os=$env:RUNNER_OS" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
4586
46-
- name: Setup Python
87+
- name: Set up Python
4788
uses: actions/setup-python@v5
4889
with:
49-
python-version: ${{ matrix.python }}
50-
cache: pip
90+
python-version: "3.12"
5191

52-
- name: Cache model caches (HF/Torch)
92+
- name: Cache pip
5393
uses: actions/cache@v4
5494
with:
55-
path: |
56-
models_cache/huggingface
57-
models_cache/torch
58-
key: windows-gpu-caches-${{ hashFiles('requirements*.txt') }}
95+
path: ${{ steps.boot.outputs.cache_dir }}
96+
key: pip-${{ steps.boot.outputs.os }}-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }}
5997
restore-keys: |
60-
windows-gpu-caches-
98+
pip-${{ steps.boot.outputs.os }}-
6199
62100
- name: Install deps
63101
run: |
64-
python -m pip install -U pip ruff
65-
pip install -r requirements.txt
66-
if exist requirements-dev.txt ( pip install -r requirements-dev.txt )
102+
python -m pip install -U pip wheel setuptools
103+
if (Test-Path "requirements.txt") { pip install -r requirements.txt }
104+
if (Test-Path "requirements-dev.txt") { pip install -r requirements-dev.txt }
105+
if (Test-Path "pyproject.toml") { pip install -e . }
67106
68-
- name: Install PyTorch CUDA wheels
107+
- name: Print Python & Torch info (if present)
108+
continue-on-error: true
69109
run: |
70-
pip install --extra-index-url https://download.pytorch.org/whl/cu124 torch torchvision torchaudio
110+
python -V
111+
$code = @'
112+
try:
113+
import torch, platform
114+
print("Torch:", torch.__version__)
115+
print("CUDA available:", torch.cuda.is_available())
116+
print("Device count:", torch.cuda.device_count() if torch.cuda.is_available() else 0)
117+
except Exception as e:
118+
print("Torch not installed:", e)
119+
'@
120+
python -c $code
71121
72-
- name: Verify CUDA is available
73-
run: |
74-
python - << 'PY'
75-
import torch, sys
76-
print("CUDA available:", torch.cuda.is_available())
77-
print("CUDA device count:", torch.cuda.device_count())
78-
sys.exit(0 if torch.cuda.is_available() else 1)
79-
PY
80-
81-
- name: Ruff (lint + fmt check)
122+
- name: Run pytest (CPU-only)
123+
env:
124+
PYTEST_ADDOPTS: "-q"
125+
run: |
126+
mkdir -Force .\test-logs | Out-Null
127+
pytest -q -m "not gpu and not gpu_cuda and not gpu_mps" --maxfail=1 --disable-warnings `
128+
--log-cli-level=INFO `
129+
2>&1 | Tee-Object -FilePath .\test-logs\pytest_cpu.txt
130+
131+
- name: Upload CPU test logs
132+
if: always()
133+
uses: actions/upload-artifact@v4
134+
with:
135+
name: logs-cpu
136+
path: test-logs/
137+
138+
tests-gpu:
139+
name: Tests (GPU)
140+
runs-on: [self-hosted, Windows, X64]
141+
needs: [tests-cpu]
142+
steps:
143+
- name: Checkout
144+
uses: actions/checkout@v4
145+
146+
- name: Bootstrap cache/env vars
147+
id: boot
148+
run: |
149+
$cacheDir = Join-Path $env:RUNNER_TEMP 'pip-cache'
150+
"cache_dir=$cacheDir" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
151+
"os=$env:RUNNER_OS" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
152+
153+
- name: Set up Python
154+
uses: actions/setup-python@v5
155+
with:
156+
python-version: "3.12"
157+
158+
- name: Cache pip
159+
uses: actions/cache@v4
160+
with:
161+
path: ${{ steps.boot.outputs.cache_dir }}
162+
key: pip-${{ steps.boot.outputs.os }}-${{ hashFiles('**/requirements*.txt', 'pyproject.toml') }}
163+
restore-keys: |
164+
pip-${{ steps.boot.outputs.os }}-
165+
166+
- name: Install deps (incl. torch from requirements*)
82167
run: |
83-
ruff --version
84-
ruff check .
85-
ruff format --check
168+
python -m pip install -U pip wheel setuptools
169+
if (Test-Path "requirements.txt") { pip install -r requirements.txt }
170+
if (Test-Path "requirements-dev.txt") { pip install -r requirements-dev.txt }
171+
if (Test-Path "pyproject.toml") { pip install -e . }
86172
87-
- name: Pytest (GPU tests)
88-
env:
89-
DEVICE: cuda
173+
- name: Show NVIDIA GPU
174+
id: nvsmi
175+
continue-on-error: true
90176
run: |
91-
pytest -q -m "gpu or gpu_cuda" --maxfail=1 -k "not slow" --durations=10
177+
$exists = Get-Command nvidia-smi -ErrorAction SilentlyContinue
178+
if ($null -eq $exists) {
179+
Write-Host "nvidia-smi not found"
180+
echo "has_gpu=false" >> $env:GITHUB_OUTPUT
181+
} else {
182+
nvidia-smi
183+
echo "has_gpu=true" >> $env:GITHUB_OUTPUT
184+
}
92185
93-
- name: Smoke test API on GPU (/health)
94-
env:
95-
DEVICE: cuda
186+
- name: Torch CUDA availability
187+
id: torchcheck
188+
continue-on-error: true
96189
run: |
97-
python scripts/smoke_test.py
190+
$code = @'
191+
try:
192+
import torch
193+
print("Torch:", torch.__version__)
194+
print("CUDA available:", torch.cuda.is_available())
195+
print("CUDA devices:", torch.cuda.device_count() if torch.cuda.is_available() else 0)
196+
except Exception as e:
197+
print("Torch not installed:", e)
198+
'@
199+
python -c $code
98200
99-
- name: Upload logs (on failure)
100-
if: failure()
101-
uses: actions/upload-artifact@v4
102-
with:
103-
name: logs-windows-gpu
104-
path: |
105-
logs/**/*.log
106-
.pytest_cache/**
107-
.ruff_cache/**
201+
- name: Run pytest (GPU markers)
202+
if: steps.nvsmi.outputs.has_gpu == 'true'
203+
env:
204+
PYTEST_ADDOPTS: "-q"
205+
run: |
206+
mkdir -Force .\test-logs | Out-Null
207+
pytest -q -m "gpu or gpu_cuda or gpu_mps" --maxfail=1 --disable-warnings `
208+
--log-cli-level=INFO `
209+
2>&1 | Tee-Object -FilePath .\test-logs\pytest_gpu.txt
210+
211+
- name: Upload GPU test logs
212+
if: always()
213+
uses: actions/upload-artifact@v4
214+
with:
215+
name: logs-gpu
216+
path: test-logs/

.github/workflows/ci-macos.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ on:
55
push:
66
branches: [ main ]
77
paths:
8-
- ".github/workflows/**"
8+
- ".github/workflows/ci-macos.yml"
99
- "app/**"
1010
- "tests/**"
1111
pull_request:
1212
paths:
13-
- ".github/workflows/**"
13+
- ".github/workflows/ci-macos.yml"
1414
- "app/**"
1515
- "tests/**"
1616

.github/workflows/ci-ubuntu.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ on:
55
push:
66
branches: [ main ]
77
paths:
8-
- ".github/workflows/**"
8+
- ".github/workflows/ci-ubuntu.yml"
99
- "app/**"
1010
- "tests/**"
1111
pull_request:
1212
paths:
13-
- ".github/workflows/**"
13+
- ".github/workflows/ci-ubuntu.yml"
1414
- "app/**"
1515
- "tests/**"
1616

.github/workflows/ci-windows.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ on:
55
push:
66
branches: [ main ]
77
paths:
8-
- ".github/workflows/**"
8+
- ".github/workflows/ci-windows.yml"
99
- "app/**"
1010
- "tests/**"
1111
pull_request:
1212
paths:
13-
- ".github/workflows/**"
13+
- ".github/workflows/ci-windows.yml"
1414
- "app/**"
1515
- "tests/**"
1616

0 commit comments

Comments
 (0)