Chatbot Icon

June 12, 2023

Cut CI Costs Now: The Hidden GitHub Actions Trick

Written By

Adam Lyth


How to

Read time

2 minute

Continuous Integration (CI) is a key part of the software development cycle, ensuring code robustness, stability, and reliability. However, the frequent execution of automated builds and tests, an essential philosophy of CI, can lead to substantial computing resource utilisation and escalating costs, especially for larger projects with numerous contributors.
What if there was a way to streamline your CI processes, reducing the need to run unnecessary steps when nothing has changed? Luckily, there is, and it's easier than you might think. We're going to discuss leveraging GitHub Actions for smart pre-checks, skipping redundant CI steps, and as a result, trimming your CI budget significantly.

Leveraging GitHub Actions for Smart Pre-checks

GitHub Actions enables an event-driven approach to workflow automation. You can configure your workflows to activate when specific events occur in your repository, such as a push or pull request. Harnessing GitHub Actions' scripting capabilities, we can create a pre-check script that identifies the changes in the latest push.
For every new push event, this script compares the current state of the repo with the previous one to pinpoint the changed files and folders. If the changes are confined to a specific module, the script then instructs to only run the CI steps related to that particular module.
The magic happens in the paths-filter GitHub Action. The filter defines a set of paths, in our case backend and frontend. If any files under these paths change, the corresponding output (either backend or frontend) will be marked as 'true'. These values can then be used in subsequent jobs to determine whether they should run or not.
Here's what this implementation might look like:
jobs: # JOB to run change detection changes: runs-on: ubuntu-latest # Required permissions permissions: pull-requests: read # Set job outputs to values from filter step outputs: backend: ${{ steps.filter.outputs.backend }} frontend: ${{ steps.filter.outputs.frontend }} steps: # For pull requests it's not necessary to checkout the code - uses: dorny/paths-filter@v2 id: filter with: filters: | backend: - 'backend/**' frontend: - 'frontend/**' # JOB to build and test backend code backend: needs: changes if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - ... # JOB to build and test frontend code frontend: needs: changes if: ${{ needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - ...
This code snippet defines two jobs to build and test backend and frontend code. They will only run if changes have been detected in their respective directories.
The reduction of unnecessary CI steps leads to less load on the CI server, faster feedback cycles, and ultimately significant cost savings.


In today's world, where software projects are becoming larger and more complex, efficient resource management is critical. Implementing smart pre-checks in your CI pipeline can drastically reduce your computing needs and lead to significant cost savings. This innovative solution is a perfect example of how clever scripting can optimise your CI/CD setup. However, remember, cost savings should never compromise code quality or robustness. When implementing this solution, ensure it aligns with your overall CI strategy.


Related posts

How did you find your chatbot experience today?

Thank you for your feedback

There has been an unexpected error, please try again later