Skip to content

replace flake8 with ruff #33

replace flake8 with ruff

replace flake8 with ruff #33

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main]
jobs:
# ---------------------------------------------------------------------------
# Job 1 — Lint + unit tests
# Runs on every pull request. No Gazebo, no GPU required.
# ---------------------------------------------------------------------------
lint-and-test:
name: Lint and unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- name: Install PyTorch (CPU build for CI)
# requirements-train.txt pins +cu121 wheels which are only on the PyTorch
# index. Install the CPU equivalents first so the rest of the deps resolve.
run: |
pip install torch==2.5.1 torchvision==0.20.1 \
--index-url https://download.pytorch.org/whl/cpu
- name: Install remaining dependencies
run: |
# Strip torch/torchvision lines (already installed above as CPU builds)
grep -v '^torch' requirements-train.txt > /tmp/req-ci.txt
pip install -r /tmp/req-ci.txt
- name: Lint
run: |
python -m ruff check train/ ocelot/ sim/ tests/
- name: Unit tests (no sim, no GPU)
# tests/sim/ require the sim container — excluded here
run: pytest tests/train/ -v --tb=short
# ---------------------------------------------------------------------------
# Job 2 — Offline model eval gate
# Runs on every push to main that changes train/, ocelot/vla_node.py, or models/.
# Blocks deployment if the model fails the pass/fail gate.
#
# Prerequisites:
# • DVC remote configured in .dvc/config (public S3, anonymous access)
# • models/vla.onnx tracked by DVC (dvc add models/vla.onnx)
# • models/vla_tokens.json committed to git (generated by export_onnx.py)
# • dataset/ tracked by DVC (dvc add dataset/)
# ---------------------------------------------------------------------------
eval:
name: Model eval gate
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- name: Install eval dependencies
# Minimal install — only what eval_onnx.py needs. No torch/GPU required.
run: |
pip install dvc h5py onnxruntime numpy tqdm transformers
- name: Pull dataset and model (DVC)
id: dvc-pull
continue-on-error: true
run: dvc pull dataset/ models/vla.onnx
- name: Run offline eval (50-episode stratified subset)
id: eval-run
if: steps.dvc-pull.outcome == 'success'
continue-on-error: true
# 50 episodes × ~100 frames ≈ 5 k frames at ~100–200 ms/frame on CPU
# ≈ 8–17 min. Stratified ensures ≥ 1 episode per label type.
run: |
python3 train/eval_onnx.py \
--model_path models/vla.onnx \
--dataset_dir dataset/ \
--split test \
--max_episodes 50 \
--stratified \
--seed 42 \
--token_cache models/vla_tokens.json \
--output eval_results.json
- name: Upload eval report
uses: actions/upload-artifact@v4
if: always()
with:
name: eval-results
path: eval_results.json
if-no-files-found: ignore
- name: Log eval result
if: always()
run: |
if [ "${{ steps.dvc-pull.outcome }}" != "success" ]; then
echo "::warning::DVC pull failed — skipping eval. Set up DVC remote + secrets to enable."
exit 0
fi
if [ "${{ steps.eval-run.outcome }}" != "success" ]; then
echo "::warning::Eval script failed — check logs above."
exit 0
fi
python3 - <<'EOF'
import json
r = json.load(open("eval_results.json"))
print(f"Episodes evaluated : {r['n_episodes']}")
print(f"Overall MSE : {r['overall_mse']:.5f} (threshold: {r['mse_threshold']})")
if r.get("per_label_mse"):
print("Per-label MSE:")
for lk, mse in sorted(r["per_label_mse"].items()):
flag = " !" if mse >= r["per_label_limit"] else " "
print(f" {flag} {lk:30s}: {mse:.5f}")
verdict = "PASS" if r["pass"] else "FAIL"
print(f"Verdict: {verdict}")
if not r["pass"]:
print("::warning::Model eval gate FAILED — see results above.")
EOF