From c6e949f62f71b0ad22cd80efc6a2b633c23a51b0 Mon Sep 17 00:00:00 2001 From: archis Date: Wed, 8 Jul 2026 16:52:13 -0700 Subject: [PATCH] ci: only run test suites for solvers changed in a PR Add a `changes` gate job (dorny/paths-filter) that maps changed paths to per-solver booleans; each test job now runs only when its solver's source, tests, or shared/core code changed. A `shared` filter (base/utils/functions/ electrostatic/normalization/driftdiffusion/mlflow, pyproject, uv.lock, run.py, conftest, this workflow, the setup action) is folded into every solver filter via a YAML anchor, so touching cross-cutting code still runs all suites. Pushes to main and manual dispatches force the full matrix (run_all) for complete coverage on the protected branch. Job names are unchanged so existing required status checks keep matching; skipped jobs report as passing. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/cpu-tests.yaml | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/.github/workflows/cpu-tests.yaml b/.github/workflows/cpu-tests.yaml index b6e0a43e..2a89bd6c 100644 --- a/.github/workflows/cpu-tests.yaml +++ b/.github/workflows/cpu-tests.yaml @@ -16,7 +16,85 @@ concurrency: cancel-in-progress: true jobs: + # Detect which solvers were touched so we only run the relevant test suites. + # `shared` catches cross-cutting code/infra and is folded into every per-solver + # filter via the &shared YAML anchor, so touching core code runs everything. + # A push to main or a manual dispatch also forces all suites (run_all == true). + changes: + runs-on: ubuntu-latest + permissions: + pull-requests: read + outputs: + run_all: ${{ steps.force.outputs.run_all }} + base: ${{ steps.filter.outputs.base }} + lpse2d: ${{ steps.filter.outputs.lpse2d }} + vlasov1d: ${{ steps.filter.outputs.vlasov1d }} + vfp1d: ${{ steps.filter.outputs.vfp1d }} + spectrax1d: ${{ steps.filter.outputs.spectrax1d }} + pic1d: ${{ steps.filter.outputs.pic1d }} + steps: + - uses: actions/checkout@v7 + - id: force + # Anything other than a pull_request (push to main, manual dispatch) runs + # the full suite for complete coverage on the protected branch. + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "run_all=false" >> "$GITHUB_OUTPUT" + else + echo "run_all=true" >> "$GITHUB_OUTPUT" + fi + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + shared: &shared + - 'pyproject.toml' + - 'uv.lock' + - 'run.py' + - '.github/workflows/cpu-tests.yaml' + - '.github/actions/setup_repo/**' + - 'tests/conftest.py' + - 'adept/__init__.py' + - 'adept/_base_.py' + - 'adept/utils.py' + - 'adept/functions.py' + - 'adept/electrostatic.py' + - 'adept/normalization.py' + - 'adept/mlflow_logging.py' + - 'adept/patched_mlflow.py' + - 'adept/driftdiffusion.py' + base: + - *shared + - 'tests/test_base/**' + lpse2d: + - *shared + - 'adept/_lpse2d/**' + - 'adept/lpse2d.py' + - 'tests/test_lpse2d/**' + vlasov1d: + - *shared + - 'adept/_vlasov1d/**' + - 'adept/vlasov1d.py' + - 'tests/test_vlasov1d/**' + vfp1d: + - *shared + - 'adept/vfp1d/**' + - 'tests/test_vfp1d/**' + - 'tests/fp_relaxation/**' + spectrax1d: + - *shared + - 'adept/_spectrax1d/**' + - 'adept/spectrax1d.py' + - 'tests/test_spectrax1d/**' + pic1d: + - *shared + - 'adept/_pic1d/**' + - 'adept/pic1d.py' + - 'tests/test_pic1d/**' + test-base: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.base == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -27,6 +105,8 @@ jobs: run: uv run --locked pytest tests/test_base test-lpse2d: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.lpse2d == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -37,6 +117,8 @@ jobs: run: uv run --locked pytest tests/test_lpse2d test-vlasov1d: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.vlasov1d == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -47,6 +129,8 @@ jobs: run: uv run --locked pytest tests/test_vlasov1d --ignore=tests/test_vlasov1d/test_config_regression.py test-vfp1d: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.vfp1d == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -57,6 +141,8 @@ jobs: run: uv run --locked pytest tests/test_vfp1d test-spectrax1d: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.spectrax1d == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -67,6 +153,8 @@ jobs: run: uv run --locked pytest tests/test_spectrax1d test-pic1d: + needs: changes + if: needs.changes.outputs.run_all == 'true' || needs.changes.outputs.pic1d == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v7