The Trimja GitHub Action will download and run trimja, cutting down the work in a Ninja-based project to only the commands affected by the files changed in the latest commit.
This can greatly speed up the time taken for your pull requests to pass CI.
To use the Trimja GitHub Action in your workflow, add the following step to your YAML configuration:
- uses: elliotgoodrich/trimja-action@v1
with:
# Version string for trimja.
# Default: '1.1.0'
version: ''
# The path to the ninja build file.
# Default: 'build.ninja'
path: ''
# Add additional string to include in the cache that describes your build
# configuration e.g. "Debug32", "arm-64", or "gcc/release/64". This
# cannot be more 100 characters.
# Default: ''
build-configuration: ''
# A list of additional files or build outputs to mark as affected.
# Default: ''
affected: ''
# Whether to pass `--explain` when running trimja, which will print out the
# reason why it is including each build command. Useful for debugging issues.
# Default: 'false'
explain: ''
Below is an example of how trimja-action
can be used as part of a CMake build.
jobs:
build:
steps:
# Step 1: Checkout the repository
- uses: actions/checkout@v4
# Step 2: Setup ninja
- uses: seanmiddleditch/gha-setup-ninja@v5
# Step 3: Configure the project using CMake
- run: >
cmake -B output
-DCMAKE_CXX_COMPILER=clang
-DCMAKE_C_COMPILER=clang
-DCMAKE_BUILD_TYPE=Debug
-G Ninja
# Step 4: Setup and run trimja
- uses: elliotgoodrich/trimja-action@v1
with:
path: output/build.ninja
build-configuration: Debug-clang
affected: |
output/extra-tests
explain: true
# Step 5: Build only those things affected by the latest commits
- run: cmake --build output --config Debug
# Step 6: Run legacy tests that aren't yet in Ninja
- run: ./output/extra-tests --run-all-tests
If you have steps in your continuous integration pipeline that are failing after running ninja, it may be because they depend on an output that is no longer being generated by ninja.
For example, if you expect an executable called myapp
to be built after
running ninja myapp
, you can encounter issues if trimja
decides not to build
myapp
because no files needed to build it have changed.
To address this, you can consider the following options:
- Put all of your logic into your ninja build file.
- Check if the required files exist and conditionally skip steps.
- Pass
myapp
to theaffected
input oftrimja-action
to ensure it is always included in the trimmed ninja build file.
To understand why trimja-action
includes each build command, you can set the
explain
input to true
. This will provide a log that lists all affected files
and the inputs to trimja
.
However, there are a few situations where more commands may be included:
- The Action cache has expired. Caches of the
.ninja_deps
and.ninja_log
files are only kept for 7 days without use. If you infrequently push changes to a repository, you may not see benefits if at least a week has passed. - The cache is older than expected. If the build fails on your default branch,
a cache will not be uploaded. So when opening a pull request from the HEAD of
your default branch, the
trimja
cache may be for an older commit. - The
build-configuration
was not supplied or is not unique across different build configurations. In this case, the wrong cache is being used, andtrimja
includes the build commands. - There may be a bug. If you suspect an issue, please open an issue on the trimja-action repository.
There are a few situations where trimja
may exclude more commands than expected:
- Your ninja build file may not correctly capture all dependencies.
- When pushing commits to a pull request,
trimja-action
compares the changes to the last successful build on that pull request. If a change does not affect any dependencies, no work is expected to be done. - There may be a bug. If you suspect an issue, please open an issue on the trimja-action repository.
- Checkout the latest commit
- Generate the ninja build file
- Lookup the latest
TRIMJA-[OS]-*
entry in Github cache - If not found, then skip to 9
- Install the cache to the ninja output directory, look at the SHA in the cache name
git fetch origin HASH
to get the cache commit- Get the list of files changed between these commits
git diff HASH..HEAD --name-only
- Run trimja
- Run ninja
- Upload the ninja files as
TRIMJA-[OS]-{HEAD}