Configuring CI Using Azure Pipelines and Nx
Below is an example of an Azure Pipelines setup building and testing only what is affected.
azure-pipelines.yml
1name: CI
2
3trigger:
4 - main
5pr:
6 - main
7
8variables:
9 CI: 'true'
10 ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
11 NX_BRANCH: $(System.PullRequest.PullRequestNumber)
12 TARGET_BRANCH: $[replace(variables['System.PullRequest.TargetBranch'],'refs/heads/','origin/')]
13 BASE_SHA: $(git merge-base $(TARGET_BRANCH) HEAD)
14 ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
15 NX_BRANCH: $(Build.SourceBranchName)
16 BASE_SHA: $(git rev-parse HEAD~1)
17 HEAD_SHA: $(git rev-parse HEAD)
18
19jobs:
20 - job: main
21 pool:
22 vmImage: 'ubuntu-latest'
23 steps:
24 - checkout: self
25 fetchDepth: 0
26 fetchFilter: tree:0
27 # Set Azure Devops CLI default settings
28 - bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject)
29 displayName: 'Set default Azure DevOps organization and project'
30 # Get last successfull commit from Azure Devops CLI
31 - bash: |
32 LAST_SHA=$(az pipelines build list --branch $(Build.SourceBranchName) --definition-ids $(System.DefinitionId) --result succeeded --top 1 --query "[0].triggerInfo.\"ci.sourceSha\"")
33 if [ -z "$LAST_SHA" ]
34 then
35 echo "Last successful commit not found. Using fallback 'HEAD~1': $BASE_SHA"
36 else
37 echo "Last successful commit SHA: $LAST_SHA"
38 echo "##vso[task.setvariable variable=BASE_SHA]$LAST_SHA"
39 fi
40 displayName: 'Get last successful commit SHA'
41 condition: ne(variables['Build.Reason'], 'PullRequest')
42 env:
43 AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
44
45 # This enables task distribution via Nx Cloud
46 # Run this command as early as possible, before dependencies are installed
47 # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
48 # Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
49 # - script: npx nx start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"
50
51 - script: npm ci --legacy-peer-deps
52 - script: git branch --track main origin/main
53 condition: eq(variables['Build.Reason'], 'PullRequest')
54
55 # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
56 # - script: npx nx-cloud record -- echo Hello World
57 - script: npx nx affected --base=$(BASE_SHA) --head=$(HEAD_SHA) -t lint test build
58 # Nx Cloud recommends fixes for failures to help you get CI green faster. Learn more: https://nx.dev/ci/features/self-healing-ci
59 - script: npx nx fix-ci
60 condition: always()
61
Get the Commit of the Last Successful Build
In the example above, we ran a script to retrieve the commit of the last successful build. The idea is to use Azure Devops CLI directly in the Pipeline Yaml
First, we configure Devops CLI
1# Set Azure Devops CLI default settings
2- bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject)
3 displayName: 'Set default Azure DevOps organization and project'
4
Then we can query the pipelines API (providing the auth token)
1# Get last successfull commit from Azure Devops CLI
2- bash: |
3 LAST_SHA=$(az pipelines build list --branch $(Build.SourceBranchName) --definition-ids $(System.DefinitionId) --result succeeded --top 1 --query "[0].triggerInfo.\"ci.sourceSha\"")
4 if [ -z "$LAST_SHA" ]
5 then
6 echo "Last successful commit not found. Using fallback 'HEAD~1': $BASE_SHA"
7 else
8 echo "Last successful commit SHA: $LAST_SHA"
9 echo "##vso[task.setvariable variable=BASE_SHA]$LAST_SHA"
10 fi
11 displayName: 'Get last successful commit SHA'
12 condition: ne(variables['Build.Reason'], 'PullRequest')
13 env:
14 AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
15
We can target a specific build; in this example, we specified:
- The branch (--branch)
- The result type (--result)
- The number of the result (--top)
The command returns an entire JSON object with all the information. But we can narrow it down to the desired result with the --query
param that uses JMESPath format (more details)
Finally, we extract the result in a common custom variable named BASE_SHA
used later by the nx format
and nx affected
commands.