I've spent longer than I care to admit on this, and am now seeking some expert Azure DevOps YAML pipeline support.
We have multiple deployment environments. Sometimes we make Terraform changes which only affect a single environment. I'm using a git diff
to determine whether or not we need to deploy to these environments.
Each environment has multiple stages - Git Diff, Pre-checks, Deployment, Post-checks
The pipeline chain therefore looks something like this:
If the Git Diff stage finds changed files related to the environment, the other stages in that environment (checks and deployment) then proceed. If not, they should be skipped, and move on to the next environment.
The Git Diff stage works fine - I ouput a changed
variable, and if it's 1
, the Pre-check stage runs as expected.
However... the deployment stage then gets skipped.
I'm using the following conditions on my stages:
- Pre-checks
condition: eq(dependencies.GitDiff_Stage_${{ parameters.env }}.outputs['GitDiff_Job.GitDiff_Task.changed'], '1')
- Deployment
condition: eq(stageDependencies.ClusterChecks_pre_${{ parameters.env }}.ClusterCheck.result, 'Succeeded')
If I change the deployment condition to always()
or not(or(failed(), canceled()))
, it runs. If I change the condition to and(always(), eq(stageDepe...
or and(not(or(failed(), canceled())), eq(stageDepe...
) it does not run.
Naturally here you would figure that the condition isn't working... but if I create a separate stage with condition always()
and run the following code:
stages:
- stage: test_${{ parameters.env }}
condition: always()
dependsOn:
- ${{ each dependency in parameters.depends_on_stage }}:
- ${{ dependency }}
jobs:
- job: test
variables:
test: $[ eq(stageDependencies.ClusterChecks_pre_${{ parameters.env }}.ClusterCheck.result, 'Succeeded') ]
steps:
- bash: |
echo "eq(stageDependencies.ClusterChecks_pre_${{ parameters.env }}.ClusterCheck.result, 'Succeeded')"
echo $(test)
... I see False
where the Pre-checks haven't run, and True
where they have - yet the deployment stage is still skipped.
So if the condition evaluates to True
, why on earth is the stage still being skipped?
All of the correct dependencies exist.
My best guess is because previous deployment jobs have been skipped.. but I don't know how to work around this.
Thanks in advance.
The expression "
stageDependencies.<stage-name>.<job-name>.result
" is for job to job dependencies across stages. It is available for the job-level and not for the stage-level.If you use this expression at stage-level, it will not be able to fetch the job result from the previous depended stage. Instead, it could get a
Null
value.For your case, at the stage-level, you can change to use the expression "
dependencies.<stage-name>.result
" to check the result of the whole previous depended stage.In addition, when you set the condition '
always()
' or 'not(or(failed(), canceled()))
' at stage-level, it just checks the status of the previous depended stage, not the status of jobs in the previous stage.for more details, see "Expressions - Dependencies".