From 962b0e6fa73d65c8c2e1179681b35ab1670cb85c Mon Sep 17 00:00:00 2001 From: ilan-gold Date: Tue, 27 May 2025 11:43:07 +0200 Subject: [PATCH 1/6] (chore): derive CI matrix from hatch env --- .github/workflows/test-cpu.yml | 103 ++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/.github/workflows/test-cpu.yml b/.github/workflows/test-cpu.yml index d38934fb3..eadc78fe7 100644 --- a/.github/workflows/test-cpu.yml +++ b/.github/workflows/test-cpu.yml @@ -22,31 +22,48 @@ concurrency: cancel-in-progress: true jobs: - pytest: + get-environments: + runs-on: ubuntu-latest + outputs: + envs: ${{ steps.get-envs.outputs.envs }} + steps: + - uses: actions/checkout@v4 + with: + filter: blob:none + fetch-depth: 0 + - uses: astral-sh/setup-uv@v5 + with: + enable-cache: false + - id: get-envs + run: | + ENVS_JSON=$(NO_COLOR=1 uvx hatch env show --json | jq -c 'to_entries + | map( + select(.key | startswith("hatch-test")) + | { + name: .key, + "test-type": (if (.key | test("pre|min")) then "coverage" else null end), + python: .value.python, + } + )') + echo "envs=${ENVS_JSON}" | tee $GITHUB_OUTPUT + test: + needs: get-environments runs-on: ubuntu-latest strategy: matrix: - include: - - python-version: '3.13' - test-type: coverage - - python-version: '3.11' - test-type: standard - - python-version: '3.13' - dependencies-version: pre-release - test-type: strict-warning - - python-version: '3.11' - dependencies-version: minimum - test-type: coverage + env: ${{ fromJSON(needs.get-environments.outputs.envs) }} + env: # environment variable for use in codecov’s env_vars tagging + ENV_NAME: ${{ matrix.env.name }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 filter: blob:none - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.env.python }} uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ matrix.env.python }} - name: Install UV uses: astral-sh/setup-uv@v5 @@ -55,43 +72,25 @@ jobs: cache-dependency-glob: pyproject.toml - name: Install dependencies - if: matrix.dependencies-version == null - run: uv pip install --system --compile -r pyproject.toml --extra=dev --extra=test -e 'anndata @ .' -c ci/constraints.txt - - - name: Install minimum dependencies - if: matrix.dependencies-version == 'minimum' - run: | - uv pip install --system --compile tomli packaging - deps=$(python3 ci/scripts/min-deps.py pyproject.toml --extras dev test-min) - uv pip install --system --compile $deps -e 'anndata @ .' - - - name: Install dependencies release candidates - if: matrix.dependencies-version == 'pre-release' - run: uv pip install -v --system --compile --pre -r pyproject.toml --extra=dev --extra=test -e 'anndata @ .' -c ci/constraints.txt - - - name: Display installed versions - run: uv pip list - - - name: Run Pytest - if: matrix.test-type == 'standard' - run: pytest -n auto - - - name: Run Pytest (coverage) - if: matrix.test-type == 'coverage' - run: coverage run -m pytest -n auto --cov --cov-report=xml - - - name: Run Pytest (treat warnings as errors) - if: matrix.test-type == 'strict-warning' - run: pytest --strict-warnings -n auto - - - uses: codecov/codecov-action@v4 - if: matrix.test-type == 'coverage' + run: uvx hatch -v env create ${{ matrix.env.name }} + + - name: Run tests + if: matrix.env.test-type == null + run: uvx hatch run ${{ matrix.env.name }}:run + - name: Run tests (coverage) + if: matrix.env.test-type == 'coverage' + run: uvx hatch run ${{ matrix.env.name }}:run-cov --cov --cov-report=xml + + - name: Upload coverage data + uses: codecov/codecov-action@v5 + if: matrix.env.test-type == 'coverage' with: token: ${{ secrets.CODECOV_TOKEN }} + env_vars: ENV_NAME fail_ci_if_error: true files: test-data/coverage.xml - check-build: + build: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -121,3 +120,15 @@ jobs: run: | pip install dist/*.whl python -c 'import anndata; print(anndata.__version__)' + + check: + if: always() + needs: + - get-environments + - test + - build + runs-on: ubuntu-latest + steps: + - uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} From 55992c1347ec85dd64442f17ae1cd44dc76ef345 Mon Sep 17 00:00:00 2001 From: ilan-gold Date: Tue, 27 May 2025 12:31:32 +0200 Subject: [PATCH 2/6] (fix): addopts for parallel --- .github/workflows/test-cpu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-cpu.yml b/.github/workflows/test-cpu.yml index eadc78fe7..6e02da188 100644 --- a/.github/workflows/test-cpu.yml +++ b/.github/workflows/test-cpu.yml @@ -8,7 +8,7 @@ on: pull_request: env: - PYTEST_ADDOPTS: "-v --color=yes" + PYTEST_ADDOPTS: "-v --color=yes -n auto --internet-tests --junitxml=test-data/test-results.xml" FORCE_COLOR: "1" defaults: From 00637c04dfdc0ccb0de2446873fc059b042bf594 Mon Sep 17 00:00:00 2001 From: ilan-gold Date: Tue, 27 May 2025 13:28:37 +0200 Subject: [PATCH 3/6] (fix): remove internet-tests flag --- .github/workflows/test-cpu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-cpu.yml b/.github/workflows/test-cpu.yml index 6e02da188..94d3e3a9d 100644 --- a/.github/workflows/test-cpu.yml +++ b/.github/workflows/test-cpu.yml @@ -8,7 +8,7 @@ on: pull_request: env: - PYTEST_ADDOPTS: "-v --color=yes -n auto --internet-tests --junitxml=test-data/test-results.xml" + PYTEST_ADDOPTS: "-v --color=yes -n auto --junitxml=test-data/test-results.xml" FORCE_COLOR: "1" defaults: From 4f08945d87f3f23c425e63161a8508f17789cb88 Mon Sep 17 00:00:00 2001 From: ilan-gold Date: Wed, 28 May 2025 11:57:25 +0200 Subject: [PATCH 4/6] (fix): scipy equality check --- src/anndata/_core/merge.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/anndata/_core/merge.py b/src/anndata/_core/merge.py index 276db242f..167efa9ab 100644 --- a/src/anndata/_core/merge.py +++ b/src/anndata/_core/merge.py @@ -189,6 +189,14 @@ def equal_sparse(a, b) -> bool: # Comparison broken for CSC matrices # https://github.com/cupy/cupy/issues/7757 a, b = CupyCSRMatrix(a), CupyCSRMatrix(b) + if Version(scipy.__version__) >= Version("1.16.0rc1"): + return bool( + a.format == b.format + and (a.shape == b.shape) + and np.all(a.indptr == b.indptr) + and np.all(a.indices == b.indices) + and np.all(a.data == b.data) + ) comp = a != b if isinstance(comp, bool): return not comp From 182e5ca1b83c6a39d4a415ef335c11bf9104e7ab Mon Sep 17 00:00:00 2001 From: ilan-gold Date: Wed, 28 May 2025 11:57:54 +0200 Subject: [PATCH 5/6] (chore): add comment --- src/anndata/_core/merge.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/anndata/_core/merge.py b/src/anndata/_core/merge.py index 167efa9ab..e75d8b112 100644 --- a/src/anndata/_core/merge.py +++ b/src/anndata/_core/merge.py @@ -190,6 +190,7 @@ def equal_sparse(a, b) -> bool: # https://github.com/cupy/cupy/issues/7757 a, b = CupyCSRMatrix(a), CupyCSRMatrix(b) if Version(scipy.__version__) >= Version("1.16.0rc1"): + # TODO: https://github.com/scipy/scipy/issues/23068 return bool( a.format == b.format and (a.shape == b.shape) From a618a86c8054f6c820118c2c30a00ee517a4c202 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Wed, 28 May 2025 17:03:52 +0200 Subject: [PATCH 6/6] simplify --- .github/workflows/test-cpu.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test-cpu.yml b/.github/workflows/test-cpu.yml index 94d3e3a9d..894ac05b4 100644 --- a/.github/workflows/test-cpu.yml +++ b/.github/workflows/test-cpu.yml @@ -8,7 +8,6 @@ on: pull_request: env: - PYTEST_ADDOPTS: "-v --color=yes -n auto --junitxml=test-data/test-results.xml" FORCE_COLOR: "1" defaults: @@ -39,11 +38,7 @@ jobs: ENVS_JSON=$(NO_COLOR=1 uvx hatch env show --json | jq -c 'to_entries | map( select(.key | startswith("hatch-test")) - | { - name: .key, - "test-type": (if (.key | test("pre|min")) then "coverage" else null end), - python: .value.python, - } + | { name: .key, python: .value.python } )') echo "envs=${ENVS_JSON}" | tee $GITHUB_OUTPUT test: @@ -75,15 +70,10 @@ jobs: run: uvx hatch -v env create ${{ matrix.env.name }} - name: Run tests - if: matrix.env.test-type == null - run: uvx hatch run ${{ matrix.env.name }}:run - - name: Run tests (coverage) - if: matrix.env.test-type == 'coverage' - run: uvx hatch run ${{ matrix.env.name }}:run-cov --cov --cov-report=xml + run: uvx hatch run ${{ matrix.env.name }}:run-cov -v --color=yes -n auto --cov --cov-report=xml --junitxml=test-data/test-results.xml - name: Upload coverage data uses: codecov/codecov-action@v5 - if: matrix.env.test-type == 'coverage' with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: ENV_NAME