Skip to content

sprint-8: stop CI hanging on the CIFAR-10 download #2

sprint-8: stop CI hanging on the CIFAR-10 download

sprint-8: stop CI hanging on the CIFAR-10 download #2

Workflow file for this run

name: CI
# Lint and the CPU test suite on every push and PR to main.
# GPU-marked tests are excluded here by design: every test in `tests/` is written
# to run on CPU in under 5 seconds, and `-m "not gpu"` is the contract that keeps
# that promise enforceable on a runner with no CUDA device.
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
# CPU-only torch. The default wheels pull ~2.5 GB of CUDA libraries that a
# runner can neither use nor fit comfortably; this index serves the same
# torch/torchvision versions built without them.
- name: Install CPU-only torch
run: |
python -m pip install --upgrade pip
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
- name: Install project
run: pip install -e ".[dev]"
- name: Lint
run: ruff check src/ tests/ scripts/
# Same three trees as the lint step above. They were src/ and tests/ only,
# which let a badly formatted file in scripts/ pass a green build.
- name: Format check
run: ruff format --check src/ tests/ scripts/
# 26 tests call build_datasets, which is download=True — without this every
# job re-fetches ~170 MB from toronto.edu, twice per push across the matrix,
# and a red badge caused by someone else's flaky host is still a red badge.
# The key is fixed: CIFAR-10 is a frozen dataset, so the cache never needs
# to be invalidated.
- name: Cache CIFAR-10
uses: actions/cache@v4
with:
path: data/
key: cifar10-python-v1
# Fetched in its own bounded step rather than lazily inside pytest. The
# first run of this workflow proved why: `pytest` inherited the download,
# produced no output for nineteen minutes, and was killed by the job
# timeout with no indication of what it had been doing. Here a stall costs
# five minutes, is attributed to the right step, and `continue-on-error`
# lets the suite proceed -- the ten dataset tests then skip visibly via
# `requires_cifar10` instead of hanging the job.
- name: Fetch CIFAR-10
continue-on-error: true
timeout-minutes: 5
run: |
python - <<'PY'
from torchvision.datasets import CIFAR10
CIFAR10(root="data", train=True, download=True)
CIFAR10(root="data", train=False, download=True)
PY
# -rs reports skip reasons, so a green build that quietly skipped the
# dataset tests is visible as such rather than looking like a full pass.
- name: Test (CPU only)
run: pytest -m "not gpu" -q -rs