Improve GitHub Actions performance by filtering out unnecessary jobs
GitHub Actions in an excellent CI/CD tool. But sometimes it gets a little annoying how much time and resources, a workflow can consume. And sometimes we have a whole workflow running with small changes that don’t require it.
So, I want to show two ways that we can choose to filter out unnecessary jobs or even steps. Personally, I recommend using both.
paths|paths-ignore
The first way is just an argument that can be included in the events on.push|pull_request
.
Let’s say, we have a workflow file called ci-example.yaml
, if we want to ignore our REAMDE.md and other markdown files that we have, we can just add the following:
name: CI Example
on:
pull_request:
paths-ignore:
- '**.md'
- LICENSE
# We can use this instead, in case we only want to run our workflow when JS files are modified
paths:
- '**.js'
build:
runs-on: ubuntu-24.04
steps:
- run: echo "Running some job..."
If you want to know more about this, just go to the following link: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore.
dorny/paths-filter
If we need something more advanced, we can use the action dorny/paths-filter
. In this case, we can create a job that check and filter all the changes, and return an output that should be used by the other jobs.
name: CI Example
jobs:
# Check and filter the changes based on the main branch
filter_changes:
runs-on: ubuntu-24.04
name: Filter changes
steps:
- uses: actions/checkout@v4
name: Determine changed files
- uses: dorny/paths-filter@v3
id: filter
with:
base: main
filters: |
css: &css
- '**.css'
js: &js
- '**.js'
sql:
- '**.sql'
# You can also use anchors to reuse paths
css_and_js:
- *css
- *js
outputs:
css: $\{{ steps.filter.outputs.css }}}
sql: $\{{ steps.filter.outputs.sql }}
css_and_js: $\{{ steps.filter.outputs.css_and_js }}
check_sql:
runs-on: ubuntu-24.04
# Run this jobs after `filter_changes` is completed successfully
needs: filter_changes
# Skip this job if there are no changes in SQL files
if: $\{{ needs.changes.outputs.sql == 'true' }}
steps:
- run: echo "Running some job..."
check_css_and_js:
runs-on: ubuntu-24.04
# Run this jobs after `filter_changes` is completed successfully
needs: filter_changes
if: $\{{ needs.changes.outputs.css_and_js == 'true' }}
steps:
- name: Check CSS
# Skip this step if there are no changes in CSS files
if: $\{{ needs.changes.outputs.css == 'true' }}
run: echo "Running some job..."
- name: Check JS
# Skip this step if there are no changes in JS files
if: $\{{ needs.changes.outputs.js == 'true' }}
run: echo "Running some job..."
If you want to know more about this action, you can go to the following link: https://github.com/marketplace/actions/paths-changes-filter.