22
33on :
44 push :
5- branches : [ "main", "master" ]
5+ branches : ["main", "master"]
66 pull_request :
7- branches : [ "main", "master" ]
7+ branches : ["main", "master"]
88
99jobs :
1010 test :
@@ -13,114 +13,117 @@ jobs:
1313 # below short-circuits otherwise so the matrix completes cleanly on
1414 # standard GitHub-hosted runners). `requirements-cpu.txt` is used when
1515 # present so CPU CI doesn't pull heavy CUDA-bound wheels.
16- name : pytest (${{ matrix.flavor }} , py${{ matrix.python-version }})
16+ name : pytest (${ matrix.flavor }, py${{ matrix.python-version }}, torch${{ matrix.torch -version }})
1717 runs-on : ubuntu-latest
1818 strategy :
1919 fail-fast : false
2020 matrix :
21- python-version : ["3.10", "3.11"]
21+ python-version : ["3.10", "3.11", "3.12" ]
2222 flavor : ["cpu"]
23+ torch-version : ["2.0", "2.1", "2.2"]
24+ exclude :
25+ - python-version : " 3.12"
26+ torch-version : " 2.0"
2327 include :
2428 - python-version : " 3.11"
2529 flavor : " gpu"
30+ torch-version : " 2.1"
2631
2732 continue-on-error : ${{ matrix.flavor == 'gpu' }}
2833
2934 steps :
30- - uses : actions/checkout@v4
31-
32- - name : Set up Python ${{ matrix.python-version }}
33- uses : actions/setup-python@v5
34- with :
35- python-version : ${{ matrix.python-version }}
36- # Issue #203: cache pip wheels keyed on all requirements files so the
37- # cache is invalidated whenever any dependency changes, but reused
38- # across runs when nothing has changed — cuts install time by ~60-80%.
39- cache : pip
40- cache-dependency-path : |
41- requirements*.txt
42-
43- # Issue #203: expose pip's wheel cache dir so the built-in setup-python
44- # cache restores pre-compiled wheels and skips compilation on cache hits.
45- - name : Install dependencies (${{ matrix.flavor }})
46- env :
47- PIP_CACHE_DIR : ~/.cache/pip
48- run : |
49- python -m pip install --upgrade pip
50- pip install pytest pytest-asyncio pytest-xdist
51- if [ "${{ matrix.flavor }}" = "cpu" ] && [ -f requirements-cpu.txt ]; then
52- pip install -r requirements-cpu.txt
53- elif [ -f requirements.txt ]; then
54- pip install -r requirements.txt
55- fi
56- # Install the package itself so `import astroml` resolves in tests.
57- pip install -e . --no-deps
58-
59- - name : Run pytest (CPU)
60- if : matrix.flavor == 'cpu'
61- # Issue #204: -p no:randomly prevents non-deterministic ordering;
62- # --forked (if available) isolates shared-state flakiness in test_dedupe.
63- # Issue #338: Run property-based tests with coverage reporting.
64- run : pytest -v -m "not gpu" -p no:randomly --tb=short --cov=astroml --cov-report=xml --cov-report=term
65-
66- - name : Upload coverage to Codecov
67- if : matrix.flavor == 'cpu'
68- uses : codecov/codecov-action@v4
69- with :
70- token : ${{ secrets.CODECOV_TOKEN }}
71- files : ./coverage.xml
72- flags : py${{ matrix.python-version }}
73- fail_ci_if_error : false
74-
75- - name : Run pytest (GPU)
76- if : matrix.flavor == 'gpu'
77- run : |
78- # The GPU subset is gated by pytest's `gpu` marker. We additionally
79- # short-circuit when CUDA isn't reachable so the job stays green on
80- # CPU-only runners until self-hosted GPU runners come online.
81- python - <<'PY'
82- import sys
83- try:
84- import torch
85- except ImportError:
86- print("torch not installed; skipping GPU pytest")
87- sys.exit(0)
88- if not torch.cuda.is_available():
89- print("CUDA not available on this runner; GPU job no-op")
90- sys.exit(0)
91- import subprocess
92- subprocess.check_call(["pytest", "-v", "-m", "gpu"])
93- PY
94-
95- # ── Issue #244: API integration tests ────────────────────────────────────────
35+ - uses : actions/checkout@v4
36+
37+ - name : Set up Python ${{ matrix.python-version }}
38+ uses : actions/setup-python@v5
39+ with :
40+ python-version : ${{ matrix.python-version }}
41+ cache : pip
42+ cache-dependency-path : |
43+ requirements*.txt
44+
45+ - name : Install dependencies (${ matrix.flavor }})
46+ env :
47+ PIP_CACHE_DIR : ~/.cache/pip
48+ run : |
49+ python -m pip install --upgrade pip
50+ pip install pytest pytest-asyncio pytest-xdist
51+
52+ # Install torch first to pin the version, then install remaining deps
53+ if [ "${{ matrix.flavor }}" = "cpu" ]; then
54+ pip install torch==${{ matrix.torch-version }}.* --index-url https://download.pytorch.org/whl/cpu
55+ else
56+ pip install torch==${{ matrix.torch-version }}.*
57+ fi
58+
59+ if [ "${{ matrix.flavor }}" = "cpu" ] && [ -f requirements-cpu.txt ]; then
60+ pip install -r requirements-cpu.txt
61+ elif [ -f requirements.txt ]; then
62+ pip install -r requirements.txt
63+ fi
64+ pip install -e . --no-deps
65+
66+ - name : Verify torch installation
67+ run : |
68+ python -c "import torch; print(f'torch {torch.__version__} installed; CUDA available: {torch.cuda.is_available()}')"
69+
70+ - name : Run pytest (CPU)
71+ if : matrix.flavor == 'cpu'
72+ run : pytest -v -m "not gpu" -p no:randomly --tb=short --cov=astroml --cov-report=xml --cov-report=term
73+
74+ - name : Upload coverage to Codecov
75+ if : matrix.flavor == 'cpu' && matrix.python-version == '3.11' && matrix.torch-version == '2.1'
76+ uses : codecov/codecov-action@v4
77+ with :
78+ token : ${{ secrets.CODECOV_TOKEN }}
79+ files : ./coverage.xml
80+ flags : py${{ matrix.python-version }}-torch${{ matrix.torch-version }}
81+ fail_ci_if_error : false
82+
83+ - name : Run pytest (GPU)
84+ if : matrix.flavor == 'gpu'
85+ run : |
86+ python - <<'PY'
87+ import sys
88+ try:
89+ import torch
90+ except ImportError:
91+ print("torch not installed; skipping GPU pytest")
92+ sys.exit(0)
93+ if not torch.cuda.is_available():
94+ print("CUDA not available on this runner; GPU job no-op")
95+ sys.exit(0)
96+ import subprocess
97+ subprocess.check_call(["pytest", "-v", "-m", "gpu"])
98+ PY
99+
96100 test-api :
97101 name : API integration tests (py3.11)
98102 runs-on : ubuntu-latest
99103
100104 steps :
101- - uses : actions/checkout@v4
102-
103- - name : Set up Python 3.11
104- uses : actions/setup-python@v5
105- with :
106- python-version : " 3.11"
107- cache : pip
108- cache-dependency-path : |
109- requirements*.txt
110-
111- - name : Install dependencies
112- env :
113- PIP_CACHE_DIR : ~/.cache/pip
114- run : |
115- python -m pip install --upgrade pip
116- pip install pytest pytest-asyncio pytest-xdist httpx fastapi sqlalchemy
117- if [ -f requirements-cpu.txt ]; then
118- pip install -r requirements-cpu.txt
119- elif [ -f requirements.txt ]; then
120- pip install -r requirements.txt
121- fi
122- pip install -e . --no-deps
123-
124- - name : Run API integration tests
125- # Uses SQLite in-memory via conftest.py — no Postgres needed in CI.
126- run : pytest api/tests/ -v --tb=short -p no:randomly
105+ - uses : actions/checkout@v4
106+
107+ - name : Set up Python 3.11
108+ uses : actions/setup-python@v5
109+ with :
110+ python-version : " 3.11"
111+ cache : pip
112+ cache-dependency-path : |
113+ requirements*.txt
114+
115+ - name : Install dependencies
116+ env :
117+ PIP_CACHE_DIR : ~/.cache/pip
118+ run : |
119+ python -m pip install --upgrade pip
120+ pip install pytest pytest-asyncio pytest-xdist httpx fastapi sqlalchemy
121+ if [ -f requirements-cpu.txt ]; then
122+ pip install -r requirements-cpu.txt
123+ elif [ -f requirements.txt ]; then
124+ pip install -r requirements.txt
125+ fi
126+ pip install -e . --no-deps
127+
128+ - name : Run API integration tests
129+ run : pytest api/tests/ -v --tb=short -p no:randomly
0 commit comments