The structure of my PR
pipeline looks like this:
trigger: none
resources:
- repo: self
variables:
- template: templates/variables.yaml
pool:
vmIMage: $(vmImageName)
stages:
- template: templates/changed.yaml
parameters:
comparedTo: origin/production
- template: templates/unitTests.yaml
- template: templates/build.yaml
parameters:
services:
- api
- admin
- admin-v2
- client
tag: test
tagVersion: latest
- template: templates/integrationTests.yaml
- template: templates/seleniumTests.yaml
The change.yaml
basically determines what microservices have been changed so that it can avoid building, testing, and deploying services if there have been no changes to them.
parameters:
- name: comparedTo
default: ''
stages:
- stage: Changed
displayName: Checks for changes in services and configs...
jobs:
- job: Changes
displayName: Checking for changes in services and configs...
steps:
- bash: |
mapfile -t servicesChanged < <(git diff HEAD ${{ parameters.comparedTo }} --name-only | awk -F'/' 'NF!=1{print $1}' | sort -u)
echo "Total Changed: ${#servicesChanged[@]}"
if [[ ${#servicesChanged[@]} > 0 ]]; then
echo "Any services changed: True"
echo "##vso[task.setvariable variable=anyServicesChanged;isOutput=true]true"
fi
name: detectChanges
There are then job conditions in subsequent stages that determine if the job should run, or not, if anyServicesChanged = true
.
What I am currently testing with, this true
always.
It gets to the unitTests.yaml
and runs normally (it passes):
stages:
- stage: UnitTests
displayName: Run unit tests on service...
condition: succeeded()
dependsOn: Changed
jobs:
- job: UnitTests
condition: or(eq(stageDependencies.Changed.Changes.outputs['detectChanges.anyServicesChanged'], true), eq(variables['Build.Reason'], 'Manual'))
displayName: Running unit tests...
steps:
- bash: |
echo "Running unit tests..."
Then it gets to build.yaml
and it skips it:
parameters:
- name: services
type: object
default: []
- name: tag
default: ''
- name: tagVersion
default: ''
stages:
- stage: BuildAndPush
displayName: Build and Push Docker images of services...
condition: succeeded()
dependsOn: UnitTests
jobs:
- job: BuildAndPush
condition: or(eq(stageDependencies.Changed.Changes.outputs['detectChanges.anyServicesChanged'], true), eq(variables['Build.Reason'], 'Manual'))
displayName: Building and Push Docker images of services...
steps:
- ${{ each service in parameters.services }}:
- task: Docker@2
displayName: Build and Push ${{ service }} Docker image
inputs:
command: buildAndPush
repository: $(imageRepository)-${{ service }}
dockerfile: $(dockerfilePath)/${{ service }}/Dockerfile
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
${{ parameters.tag }}-${{ parameters.tagVersion }}
The job condition:
is exactly the same, but this time it says it is NULL
:
6 queue time variables used
Expanded: or(eq(Null, True), eq('PullRequest', 'Manual'))
Result: False
I'm not sure why this is as I thought it would persist where every I need to use that variable.
Suggestions for why this is happening and how to fix it?