sprint-8: stop CI hanging on the CIFAR-10 download #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |