Skip to content

chore(ci): skip expensive jobs on non-source changes#565

Open
cameri wants to merge 2 commits intomainfrom
chore/optimize-ci-path-filters
Open

chore(ci): skip expensive jobs on non-source changes#565
cameri wants to merge 2 commits intomainfrom
chore/optimize-ci-path-filters

Conversation

@cameri
Copy link
Copy Markdown
Owner

@cameri cameri commented Apr 22, 2026

Summary

  • Adds a changes job using dorny/paths-filter@v3 to detect whether source-affecting files changed (src/, test/, package.json, tsconfig*.json, biome.json, .knip.json, Dockerfiles, .nvmrc, and the workflow file itself)
  • Gates lint, build-check, and both test jobs behind needs.changes.outputs.src == 'true' so they skip on docs/config-only PRs
  • Fixes commit-lint false positives on squash-merges by restricting it to pull_request and workflow_dispatch only
  • Guards post-tests Coveralls parallel-finished signal to only fire when at least one test job ran (prevents spurious 0% coverage reports)
  • Bumps actions/checkout and actions/setup-node from @v3@v4

Why job-level filter instead of trigger-level paths:

GitHub only satisfies required status checks when a job actually runs. A trigger-level paths: filter skips the entire workflow, leaving required checks unsatisfied and blocking PRs. The job-level approach keeps the workflow running but skips expensive jobs internally.

Test plan

  • Open a PR touching only a .md file → lint, build-check, test-units-and-cover, test-integrations-and-cover show as Skipped (green) in Checks
  • Open a PR touching a file in src/ → all jobs run normally
  • Push directly to maincommit-lint is skipped, changesets.yml runs as before
  • Trigger workflow_dispatch → all jobs run (path-filter returns true with no diff)

🤖 Generated with Claude Code

Add dorny/paths-filter gate so lint, build-check, and both test jobs
only run when source-affecting files change (src/, test/, package.json,
tsconfigs, Dockerfiles, etc.). Metadata checks (commit-lint,
changeset-check) remain unconditional.

Also restrict commit-lint to PRs/workflow_dispatch to avoid false
positives on squash-merge commits pushed to main, fix post-tests
Coveralls parallel-finished to not fire on skipped test runs, and bump
actions/checkout + actions/setup-node from v3 to v4.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 22, 2026

🦋 Changeset detected

Latest commit: c65405e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coveralls
Copy link
Copy Markdown
Collaborator

Coverage Status

coverage: 74.929%. remained the same — chore/optimize-ci-path-filters into main

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates CI to avoid running expensive lint/build/test jobs when a PR only changes non-source files, while keeping required checks satisfied and reducing Coveralls noise.

Changes:

  • Add a changes job (paths filter) and gate lint, build-check, and test jobs on needs.changes.outputs.src.
  • Restrict commit-lint to pull_request and workflow_dispatch; guard Coveralls “parallel-finished”.
  • Bump actions/checkout / actions/setup-node to v4 and add @changesets/changelog-github to devDependencies.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.

File Description
.github/workflows/checks.yml Adds changed-path detection and conditions to skip expensive jobs; updates action versions; adjusts Coveralls signaling.
package.json Adds @changesets/changelog-github devDependency; normalizes author string.
package-lock.json Locks dependencies added by @changesets/changelog-github.
.changeset/proud-pants-cry.md Adds a changeset entry for the PR.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +105 to +106
needs.lint.result != 'failure' &&
needs.build-check.result != 'failure'
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit test job condition allows execution when lint/build-check are cancelled (because it only blocks failure). If the intent is to only run tests after those jobs succeed, change the condition to require needs.lint.result == 'success' and needs.build-check.result == 'success'.

Suggested change
needs.lint.result != 'failure' &&
needs.build-check.result != 'failure'
needs.lint.result == 'success' &&
needs.build-check.result == 'success'

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +147
if: |
always() &&
needs.changes.outputs.src == 'true' &&
needs.lint.result != 'failure' &&
needs.build-check.result != 'failure'
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the unit test job: the integration test job condition only blocks on failure, so tests may still run if lint/build-check were cancelled. If dependencies must pass, require needs.lint.result == 'success' and needs.build-check.result == 'success' instead.

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +196
- name: Coveralls Finished
uses: coverallsapp/github-action@master
if: |
needs.test-units-and-cover.result != 'skipped' ||
needs.test-integrations-and-cover.result != 'skipped'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
parallel-finished: true
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coverallsapp/github-action@master is a floating ref, which is risky for supply-chain security and can introduce unexpected CI changes. Pin this to a stable release tag or (preferably) a commit SHA.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +23
permissions:
pull-requests: read
outputs:
src: ${{ steps.filter.outputs.src }}
steps:
- uses: actions/checkout@v4
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes job sets a job-level permissions block with only pull-requests: read. When job permissions are set, any unspecified scopes default to none, which can break actions/checkout (it needs contents: read). Add contents: read (and keep pull-requests: read if you want API-based PR file listing).

Copilot uses AI. Check for mistakes.
outputs:
src: ${{ steps.filter.outputs.src }}
steps:
- uses: actions/checkout@v4
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dorny/paths-filter relies on git history for non-PR events (e.g., push), but actions/checkout here uses the default shallow clone. Configure actions/checkout with an appropriate fetch-depth (commonly 0 or at least 2) so the action can diff github.event.before..after reliably.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
fetch-depth: 0

Copilot uses AI. Check for mistakes.
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.

4 participants