Reputation: 103
I have an azure devops pipeline which run as follow:
parameters:
- name: environments
type: object
default:
- a
- b
stages:
- ${{ each env in parameters.environments }}:
- stage: Plan_${{ env }}
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
jobs:
- job: Plan
steps:
- template: s1.yml
parameters:
env: ${{ env }}
action: plan
workingDirectory: '${{ parameters.workingDirectory }}'
- stage: Apply_${{ env }}
dependsOn: Plan_${{ env }}
condition: and(succeeded(), eq(dependencies.Plan_${{ env }}.outputs['Plan.x.y'], 'true')) #where x is a task from template s1.yml and y is the output variable;
jobs:
.................
Running this pipeline, it runs sequential not as I wish, I need. I need to have something like:
Currently, it is working as: considering no changes for both environment, pipeline starts with plan.a, it matches the condition then it skips apply.a, skips plan.b and apply.b .
I tried in parallel mode, introducing before Plan a new stage and to make Plan to depends by that stage and they working in parallel, but in sequent mode, how to make it works as I need?
ps: I tried excluding dependsOn, not working; I tried with parallel depending on another previous stage if I create it but I need it in sequential mode.
I tried this way:
stages:
- ${{ each env in parameters.environments }}:
- stage: Plan_${{ env }}
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
jobs:
- job: Plan
steps:
- template: s1.yml
parameters:
env: ${{ env }}
action: plan
workingDirectory: '${{ parameters.workingDirectory }}'
**- ${{ each env in parameters.environments }}:**
- stage: Apply_${{ env }}
dependsOn: Plan_${{ env }}
condition: and(succeeded(), eq(dependencies.Plan_${{ env }}.outputs['Plan.x.y'], 'true')) #where x is a task from template s1.yml and y is the output variable;
jobs:
.................
and the pipeline now is working in this way: starts with plan.a (finishing it, result no changes), continue with plan.b (result no changes) then skipping apply.a , skipping apply.b .
I need them to be sequentially plan.a, apply.a; plan.b, apply.b and skipping the apply after each plan stage started and having an output variable that match or not condition.
Upvotes: 2
Views: 624
Reputation: 726
Add dependsOn: []
on in the Plan_${{ env }}
stage:
parameters:
- name: environments
type: object
default:
- a
- b
stages:
- ${{ each env in parameters.environments }}:
- stage: Plan_${{ env }}
condition: and(succeeded(), ne(variables['Build.Reason'], 'Manual'))
dependsOn: []
jobs:
- job: Plan
steps:
- task: PowerShell@2
name: SetVariable
inputs:
targetType: "inline"
script: |
Write-Host "##vso[task.setvariable variable=runApply;isOutput=true]false"
- stage: Apply_${{ env }}
dependsOn: Plan_${{ env }}
condition: and(succeeded(), eq(dependencies.Plan_${{ env }}.outputs['Plan.SetVariable.runApply'], 'true'))
jobs:
- job: Apply
steps:
- task: PowerShell@2
name: SetVariable
inputs:
targetType: "inline"
script: |
Write-Host "Running Apply"
Output:
The reason Plan_B is being blocked is because the stage before it is in a skipped state, which is not succeeded. To get around this we can alter the condition from succeeded()
to not(or(failed(), canceled()))
.
parameters:
- name: environments
type: object
default:
- a
- b
stages:
- ${{ each env in parameters.environments }}:
- stage: Plan_${{ env }}
condition: and(not(or(failed(), canceled())), ne(variables['Build.Reason'], 'Manual'))
jobs:
- job: Plan
steps:
- task: PowerShell@2
name: SetVariable
inputs:
targetType: "inline"
script: |
Write-Host "##vso[task.setvariable variable=runApply;isOutput=true]false"
- stage: Apply_${{ env }}
dependsOn: Plan_${{ env }}
condition: and(not(or(failed(), canceled())), eq(dependencies.Plan_${{ env }}.outputs['Plan.SetVariable.runApply'], 'true'))
jobs:
- job: Apply
steps:
- task: PowerShell@2
name: SetVariable
inputs:
targetType: "inline"
script: |
Write-Host "Running Apply"
Output:
Upvotes: 2