Improve GitHub Actions performance by filtering out unnecessary jobs

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.

#github #actions #programming

365 views
0 reactions
0 comments
(edited)

Reactions

Comments