Configuring CI Using GitHub Actions and Nx
Below is an example of a GitHub setup for an Nx workspace - building and testing only what is affected. For more details on how the action is used, head over to the official docs.
1name: CI
2on:
3 push:
4 branches:
5 - main
6 pull_request:
7
8jobs:
9 main:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@v4
13 with:
14 fetch-depth: 0
15 - uses: actions/setup-node@v3
16 with:
17 node-version: 20
18 cache: 'npm'
19 - run: npm ci
20 - uses: nrwl/nx-set-shas@v3
21 - run: git branch --track main origin/main
22
23 - run: npx nx format:check
24 - run: npx nx affected -t lint,test,build --parallel=3
25
GitHub
can track the last successful run on the main
branch and use this as a reference point for the BASE
. The Nx Set SHAs
provides a convenient implementation of this functionality which you can drop into your existing CI config. To understand why knowing the last successful build is important for the affected command, check out the in-depth explanation in Actions's docs.
Distributed Task Execution with Nx Cloud
Read more about Distributed Task Execution (DTE). Use this reusable GitHub workflow to quickly set up DTE for your organization.
1name: CI
2on:
3 push:
4 branches:
5 - main
6 pull_request:
7
8jobs:
9 main:
10 name: Nx Cloud - Main Job
11 uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.13.0
12 with:
13 number-of-agents: 3
14 parallel-commands: |
15 npx nx-cloud record -- npx nx format:check
16 parallel-commands-on-agents: |
17 npx nx affected -t lint,test,build --parallel=3
18
19 agents:
20 name: Nx Cloud - Agents
21 uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.13.0
22 with:
23 number-of-agents: 3
24
You can also use our ci-workflow generator to generate the workflow file.
Custom distributed CI with Nx Cloud
Our reusable GitHub workflow represents a good set of defaults that works for a large number of our users. However, reusable GitHub workflows come with their limitations.
If the reusable workflow above doesn't satisfy your needs you should create a custom workflow. This is what the GitHub workflow above roughly encapsulates:
1name: CI
2on:
3 push:
4 branches:
5 - main
6 pull_request:
7
8env:
9 NX_CLOUD_DISTRIBUTED_EXECUTION: true # this enables DTE
10 NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 3 # expected number of agents
11 NX_BRANCH: ${{ github.event.number || github.ref_name }}
12 NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
13 NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # this is needed if our pipeline publishes to npm
14
15jobs:
16 main:
17 name: Nx Cloud - Main Job
18 runs-on: ubuntu-latest
19 steps:
20 - uses: actions/checkout@v4
21 name: Checkout [Pull Request]
22 if: ${{ github.event_name == 'pull_request' }}
23 with:
24 # By default, PRs will be checked-out based on the Merge Commit, but we want the actual branch HEAD.
25 ref: ${{ github.event.pull_request.head.sha }}
26 # We need to fetch all branches and commits so that Nx affected has a base to compare against.
27 fetch-depth: 0
28
29 - uses: actions/checkout@v4
30 name: Checkout [Default Branch]
31 if: ${{ github.event_name != 'pull_request' }}
32 with:
33 # We need to fetch all branches and commits so that Nx affected has a base to compare against.
34 fetch-depth: 0
35
36 # Set node/npm/yarn versions using volta
37 - uses: volta-cli/action@v4
38 with:
39 package-json-path: '${{ github.workspace }}/package.json'
40
41 - name: Use the package manager cache if available
42 uses: actions/setup-node@v3
43 with:
44 node-version: 20
45 cache: 'npm'
46
47 - name: Install dependencies
48 run: npm ci
49
50 - name: Check out the default branch
51 run: git branch --track main origin/main
52
53 - name: Initialize the Nx Cloud distributed CI run
54 run: npx nx-cloud start-ci-run
55
56 - name: Run commands in parallel
57 run: |
58 pids=()
59 # list of commands to be run on main has env flag NX_CLOUD_DISTRIBUTED_EXECUTION set to false
60 NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx-cloud record -- npx nx format:check & pids+=($!)
61
62 # list of commands to be run on agents
63 npx nx affected -t lint,test,build --parallel=3 &
64 pids+=($!)
65
66 # run all commands in parallel and bail if one of them fails
67 for pid in ${pids[*]}; do
68 if ! wait $pid; then
69 exit 1
70 fi
71 done
72
73 exit 0
74
75 - name: Stop all running agents for this CI run
76 # It's important that we always run this step, otherwise in the case of any failures in preceding non-Nx steps, the agents will keep running and waste billable minutes
77 if: ${{ always() }}
78 run: npx nx-cloud stop-all-agents
79
80 agents:
81 name: Agent ${{ matrix.agent }}
82 runs-on: ubuntu-latest
83 strategy:
84 matrix:
85 agent: [1, 2, 3]
86 steps:
87 - name: Checkout
88 uses: actions/checkout@v4
89
90 # Set node/npm/yarn versions using volta
91 - uses: volta-cli/action@v4
92 with:
93 package-json-path: '${{ github.workspace }}/package.json'
94
95 - name: Use the package manager cache if available
96 uses: actions/setup-node@v3
97 with:
98 node-version: 20
99 cache: 'npm'
100
101 - name: Install dependencies
102 run: npm ci
103
104 - name: Start Nx Agent ${{ matrix.agent }}
105 run: npx nx-cloud start-agent
106 env:
107 NX_AGENT_NAME: ${{ matrix.agent }}
108