What i want to achieve:
After all deployment jobs i want to run powershell script, but knowing which branch has triggered this pipeline run, and whether all deployment jobs succeeded or not.
My pipeline looks like this:
trigger:
branches:
include:
- qa
- main
variables:
- name: targetEnv
${{ if in(variables['Build.SourceBranch'], 'refs/heads/qa') }}:
value: $(QA)
${{ elseif eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
value: $(PROD)
${{ else }}:
value: "Unknown"
stages:
- stage: CI
jobs:
- job: Build
pool:
vmImage: windows-latest
steps:
(... some tasks)
- stage: CD
jobs:
- deployment: MyUi_deploy
strategy:
runOnce:
deploy:
steps:
(... some tasks)
- deployment: 'ServiceOne_deploy'
strategy:
runOnce:
deploy:
steps:
(... some tasks)
- job: StartMyPSscript
displayName: 'Here i want to be after all deployments are completed'
steps:
(... some tasks)
I want job "StartMyPSscript" to be started after all "deployment" steps are completed, and in this "StartMyPSscript" step i need to know whether deployment steps failed, or succeeded
I have tried to do this part like:
- job: StartMyPSscript_Failure
displayName: 'Here i want to be after all deployments are completed but any of them failed'
dependsOn:
- MyUi_deploy
- ServiceOne_deploy
condition: and(eq(variables['targetEnv'], variables['QA']), failed())
- job: StartMyPSscript_Success
displayName: 'Here i want to be after all deployments are completed succesfully'
dependsOn:
- MyUi_deploy
- ServiceOne_deploy
condition: and(eq(variables['targetEnv'], variables['QA']), succeeded())
But it didn't work, none of these jobs were started - i assume that using failed()
or succeeded()
within job, not stage is not working as intended.
Then i tried doing it like:
- job: StartMyPSscript
displayName: 'Here i want to be after all above deployments are completed'
dependsOn:
- MyUi_deploy
- ServiceOne_deploy
steps:
- task: PowerShell@2
condition: and(eq(variables['targetEnv'], variables['QA']), succeeded())
displayName: 'Success'
inputs:
targetType: 'inline'
script: (some script)
- task: PowerShell@2
condition: and(eq(variables['targetEnv'], variables['QA']), failed())
displayName: 'Failure'
inputs:
targetType: 'inline'
script: (some script)
But it was also a fail, due to problem with variables (?):
Evaluating: eq(variables['targetEnv'], variables['QA'])
Expanded: eq('$(QA)', 'MyApp QA')
Result: False
Where QA
is of course defined in Variables of this Pipeline to 'MyApp QA'
So question is - how to do it properly, with all standards and best practices
Test the same YAML sample and I can reproduce the same issue.
From your YAML sample, you are using the nested variable: targetEnv in condition.
When you use the format $(varname)
in Pipeline condition to get the actual value of nested variable, it is not passed correctly. This is because this format processes the variable at runtime before a task/job executes. At this point in time, the variable value has not been set correctly.
To solve this issue, you can use the format: $[variables.var]
to set the targetEnv variable value. This format will process the variable at runtime.
YAML sample:
variables:
- name: targetEnv
${{ if in(variables['Build.SourceBranch'], 'refs/heads/qa') }}:
value: $[variables.QA]
${{ elseif eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
value: $[variables.PROD]
${{ else }}:
value: "Unknown"
stages:
- stage: CI
jobs:
- job: Build
pool:
vmImage: windows-latest
steps:
(... some tasks)
- stage: CD
jobs:
- deployment: MyUi_deploy
strategy:
runOnce:
deploy:
steps:
(... some tasks)
- deployment: 'ServiceOne_deploy'
strategy:
runOnce:
deploy:
steps:
(... some tasks)
- job: StartMyPSscript_Failure
displayName: 'Here i want to be after all deployments are completed but any of them failed'
dependsOn:
- MyUi_deploy
- ServiceOne_deploy
condition: and(eq(variables['targetEnv'], variables['QA']), failed())
- job: StartMyPSscript_Success
displayName: 'Here i want to be after all deployments are completed succesfully'
dependsOn:
- MyUi_deploy
- ServiceOne_deploy
condition: and(eq(variables['targetEnv'], variables['QA']), succeeded())
Result:
For more detailed info, you can refer to this doc: Runtime expression syntax