Skip to content

ci: run package tests only for the packages whose code changed - #405

Merged
lachlangrose merged 1 commit into
masterfrom
ci/path-filtered-package-tests
Nov 6, 2026
Merged

lachlangrose merged 1 commit into
masterfrom
ci/path-filtered-package-tests

Conversation

@lachlangrose

Copy link
Copy Markdown
Member

Summary

The workflow packages.yml ran every package test job, map2loop and the root suite whenever anything under packages/ changed. A change in one package paid for all of them: about 15 minutes for the root suite on three Python versions and several operating systems.

A new changes job now decides which jobs run. On a pull request, a change runs its own tests and the tests of the code that depends on it:

Changed code Tests that run
packages/loop_common loop_common, loop_interpolation, visualisation, root suite
packages/loop_interpolation loop_interpolation, visualisation, root suite
LoopStructural/, tests/, pyproject.toml root suite, visualisation
packages/loopstructural_visualisation visualisation
packages/map2loop map2loop
uv.lock, .github/workflows/packages.yml everything

This follows the dependencies in the pyproject.toml files: loop-interpolation needs loop-common, the root package needs both, loopstructuralvisualisation needs LoopStructural, and map2loop needs none of them.

A push to master and a manual run still run everything.

Details

  • The changes job uses dorny/paths-filter@v3. It outputs the list of packages for the packages-test matrix, a flag for map2loop-test and a flag for the root suite. The decision is a short bash step in the workflow.
  • packages-test and map2loop-test are skipped when they are not needed. The root suite uses always() so that a skipped job in needs does not skip it. It still stops if a job it waits for failed or was cancelled.
  • The workflow now also triggers on changes in LoopStructural/**, tests/**, pyproject.toml and uv.lock. Before, a pull request that changed only the root package did not start this workflow at all. This is a change in coverage: those pull requests now run the root suite with uv, as the package pull requests already did. tester.yml is not changed.
  • A skipped job shows as skipped, not failed. If a branch protection rule requires one of these checks, a skipped check counts as passed.

Test plan

  • The workflow file parses as YAML, and the job dependencies are as intended.
  • The selection step was run locally for nine cases (only map2loop, only loop_common, only loop_interpolation, only visualisation, only the root package, uv.lock or the workflow, nothing relevant, a push, a manual run). Each gave the table above, and the package list was valid JSON in each case.
  • This pull request changes packages.yml, so it runs everything. It does not show the filtering. The first pull request after it merges shows the filtering. A pull request that touches only one package is a good check.
  • GitHub Actions cannot run locally. The only part that I could not test is the dorny/paths-filter step and the if expression with always().

A pull request now runs the test jobs of the packages it changes and of the
code that depends on them. A push to master, a manual run, and a change to
uv.lock or to this workflow run everything.
@lachlangrose
lachlangrose merged commit 5b0cee9 into master Nov 6, 2026
45 checks passed
@lachlangrose
lachlangrose deleted the ci/path-filtered-package-tests branch November 6, 2026 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant