ci(mutation): run mutation tests only when src/ or test/ changed - #30
Conversation
Infection is the slowest CI job (full coverage run + thousands of mutants), and it can only change outcome when the mutated code (src/) or the tests that kill mutants (test/) change. Gate it: a `changes` job (dorny/paths-filter) detects whether src/ or test/ was touched, and the `infection` job runs only when it was — so a docs- or config-only PR skips mutation entirely. The `needs: phpunit` ordering is preserved (mutation still waits for unit tests).
|
| Filename | Overview |
|---|---|
| .github/workflows/ci-core.yml | Adds a changes job using dorny/paths-filter@v3 to gate the expensive infection job on src/ or test/ modifications; works correctly for pull_request events but shallow-clone behavior on push-to-main is worth verifying. |
Reviews (1): Last reviewed commit: "ci(mutation): run mutation tests only wh..." | Re-trigger Greptile
| - uses: actions/checkout@v4 | ||
| - uses: dorny/paths-filter@v3 | ||
| id: filter | ||
| with: | ||
| filters: | | ||
| code: | ||
| - 'src/**' | ||
| - 'test/**' |
There was a problem hiding this comment.
Shallow clone may force extra fetches on push-to-main
For pull_request events, dorny/paths-filter uses the GitHub API (no git history needed), so the current setup is perfectly correct there. For push events to main, the action needs to compare against github.event.before, which isn't present in the default fetch-depth: 1 shallow clone. The action recovers by calling git fetch --deepen in a loop until the merge-base is found, but this adds unnecessary network round-trips on every push to main. Adding fetch-depth: 0 to the checkout step (or setting the base input) avoids the extra fetching and makes the behavior explicit.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Declining. Accurate that on push to main, dorny deepens the shallow clone to reach github.event.before.
But the suggested fix trades the wrong way:
- On
pull_request: the event that actually gates mutation on feature branches — dorny uses the GitHub API and touches no git history, so the shallow checkout is already optimal (fetch-depthis irrelevant there). - On push to
main, before is the previous tip, so it's typically 1–2 incremental fetches. That's trivial. fetch-depth: 0clones the entire history on every run (all PRs and pushes), including the PR runs where dorny doesn't use git at all.
There was a problem hiding this comment.
You're right. The trade-off math is clearly against fetch-depth: 0 — paying a full history clone on every PR (where dorny never touches git) just to save 1–2 incremental fetches on push-to-main is the wrong direction. The current shallow checkout is the better default. Thanks for the clear breakdown.
Infection is the slowest CI job (full coverage run + thousands of mutants), and it can only change outcome when the mutated code (src/) or the tests that kill mutants (test/) change. Gate it: a
changesjob (dorny/paths-filter) detects whether src/ or test/ was touched, and theinfectionjob runs only when it was — so a docs- or config-only PR skips mutation entirely. Theneeds: phpunitordering is preserved (mutation still waits for unit tests).