Pijplijnvoorwaarden
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
In dit artikel worden de voorwaarden beschreven waaronder een Azure Pipelines-fase, -taak of -stap wordt uitgevoerd en hoe u verschillende voorwaarden opgeeft. Zie de belangrijkste concepten voor Azure Pipelines voor meer context over fasen, taken en stappen.
Een taak of fase wordt standaard uitgevoerd als deze niet afhankelijk is van een andere taak of fase, of als alle afhankelijkheden zijn voltooid en geslaagd. Deze vereiste geldt niet alleen voor directe afhankelijkheden, maar voor hun indirecte afhankelijkheden, die recursief worden berekend.
Standaard wordt een stap uitgevoerd als er nog niets in de taak is mislukt en de stap direct voordat deze is voltooid.
U kunt dit gedrag overschrijven of aanpassen door een fase, taak of stap af te dwingen, zelfs als een eerdere afhankelijkheid mislukt of door een aangepaste voorwaarde op te geven.
Notitie
In dit artikel worden de mogelijkheden van YAML-pijplijnen besproken. Voor klassieke pijplijnen kunt u bepaalde voorwaarden opgeven waaronder taken of taken worden uitgevoerd in de beheeropties van elke taak en in de aanvullende opties voor een taak in een release-pijplijn.
Voorwaarden waaronder een fase, taak of stap wordt uitgevoerd
In de YAML van de pijplijndefinitie kunt u de volgende voorwaarden opgeven waaronder een fase, taak of stap wordt uitgevoerd:
Alleen wanneer alle vorige directe en indirecte afhankelijkheden met dezelfde agentgroep slagen. Als u verschillende agentpools hebt, worden deze fasen of taken gelijktijdig uitgevoerd. Deze voorwaarde is de standaardvoorwaarde als er geen voorwaarde is ingesteld in de YAML.
Zelfs als een eerdere afhankelijkheid mislukt, tenzij de uitvoering wordt geannuleerd. Gebruik
succeededOrFailed()
in de YAML voor deze voorwaarde.Zelfs als een eerdere afhankelijkheid mislukt en zelfs als de uitvoering wordt geannuleerd. Gebruik
always()
in de YAML voor deze voorwaarde.Alleen wanneer een eerdere afhankelijkheid mislukt. Gebruik
failed()
in de YAML voor deze voorwaarde.
- Aangepaste voorwaarden.
Fasen, taken en stappen worden standaard uitgevoerd als alle directe en indirecte afhankelijkheden slagen. Deze status is hetzelfde als het opgeven condition: succeeded()
. Zie de functie Geslaagde status voor meer informatie.
Wanneer u een condition
eigenschap opgeeft voor een fase, taak of stap, overschrijft u de standaardwaarde condition: succeeded()
. Als u uw eigen voorwaarden opgeeft, kan dit ertoe leiden dat uw fase, taak of stap wordt uitgevoerd, zelfs als de build is geannuleerd. Zorg ervoor dat de voorwaarden die u schrijft rekening houden met de status van de bovenliggende fase of taak.
In het volgende YAML-voorbeeld ziet u de always()
en failed()
voorwaarden. De stap in de eerste taak wordt uitgevoerd, zelfs als afhankelijkheden mislukken of als de build wordt geannuleerd. De tweede taak wordt alleen uitgevoerd als de eerste taak mislukt.
jobs:
- job: Foo
steps:
- script: echo Hello!
condition: always() # this step runs, even if the build is canceled
- job: Bar
dependsOn: Foo
condition: failed() # this job runs only if Foo fails
U kunt ook variabelen instellen en gebruiken in voorwaarden. In het volgende voorbeeld wordt een isMain
variabele ingesteld en gebruikt om aan te wijzen main
als de Build.SourceBranch
.
variables:
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
stages:
- stage: A
jobs:
- job: A1
steps:
- script: echo Hello Stage A!
- stage: B
condition: and(succeeded(), eq(variables.isMain, true))
jobs:
- job: B1
steps:
- script: echo Hello Stage B!
- script: echo $(isMain)
Belangrijk
Voorwaarden worden geëvalueerd om te bepalen of een fase, taak of stap moet worden gestart. Daarom is er niets berekend tijdens runtime binnen die werkeenheid. Als u bijvoorbeeld een taak hebt waarmee een variabele wordt ingesteld met behulp van een runtime-expressie met $[ ]
syntaxis, kunt u die variabele niet gebruiken in een aangepaste voorwaarde in die taak.
Aangepaste voorwaarden
Als de ingebouwde voorwaarden niet aan uw behoeften voldoen, kunt u aangepaste voorwaarden opgeven. U schrijft voorwaarden als expressies in YAML-pijplijndefinities.
De agent evalueert de expressie die begint met de binnenste functie en gaat naar buiten. Het uiteindelijke resultaat is een Booleaanse waarde die bepaalt of de taak, taak of fase moet worden uitgevoerd. Zie Expressies voor een volledige handleiding voor de syntaxis.
Als een van uw voorwaarden ervoor zorgt dat de taak kan worden uitgevoerd, zelfs nadat de build is geannuleerd, geeft u een redelijke waarde op voor time-outs voor annuleren, zodat deze taken voldoende tijd hebben om te voltooien nadat de gebruiker een uitvoering heeft geannuleerd.
Resultaten van voorwaarde wanneer een build wordt geannuleerd
Als u een build annuleert, betekent dit niet dat alle fasen, taken of stappen niet meer worden uitgevoerd. Welke fasen, taken of stappen niet meer worden uitgevoerd, is afhankelijk van de opgegeven voorwaarden en op welk moment van de uitvoering van de pijplijn u de build hebt geannuleerd. Als een bovenliggende fase, taak of stap wordt overgeslagen, wordt de taak niet uitgevoerd, ongeacht de voorwaarden.
Een fase, taak of stap wordt uitgevoerd wanneer de voorwaarden worden true
geëvalueerd. Als uw voorwaarde niet rekening houdt met de status van de bovenliggende taak, kan de taak worden uitgevoerd, zelfs als het bovenliggende item wordt geannuleerd. Als u wilt bepalen of fasen, taken of stappen met voorwaarden worden uitgevoerd wanneer een build wordt geannuleerd, moet u een functie voor taakstatuscontrole opnemen in uw voorwaarden.
In de volgende voorbeelden ziet u de resultaten van verschillende voorwaarden die zijn ingesteld voor fasen, taken of stappen wanneer de build wordt geannuleerd.
Fasevoorbeeld 1
In de volgende pijplijn is standaard stage2
afhankelijk stage1
van, maar stage2
moet deze condition
worden uitgevoerd wanneer de bronbranch zich bevindt main
, ongeacht stage1
de status.
Als u een build in de wachtrij op de main
vertakking zet en deze annuleert terwijl stage1
deze wordt uitgevoerd, stage2
wordt deze nog steeds uitgevoerd, omdat eq(variables['Build.SourceBranch'], 'refs/heads/main')
dit true
wordt geëvalueerd.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
jobs:
- job: B
steps:
- script: echo 2
Fasevoorbeeld 2
In de volgende pijplijn stage2
is standaard afhankelijk stage1
van. Job B
in stage2
heeft een condition
set. Als u een build op de vertakking in de main
wachtrij zet en deze annuleert terwijl stage1
deze wordt uitgevoerd, wordt deze niet uitgevoerd, stage2
ook al bevat het een taak waarvan de voorwaarde wordt geëvalueerd true
.
De reden hiervoor is dat stage2
de standaardwaarde condition: succeeded()
is, die evalueert false
wanneer stage1
wordt geannuleerd. Daarom wordt stage2
overgeslagen en worden de taken niet uitgevoerd.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo 2
Fasevoorbeeld 3
In de volgende pijplijn is standaard stage2
afhankelijk stage1
van en de stap in de taak B
heeft een condition
set.
Als u een build op de main
vertakking in de wachtrij zet en deze annuleert terwijl stage1
deze wordt uitgevoerd, wordt deze niet uitgevoerd, stage2
ook al bevat het een stap in de taak B
waarvan de voorwaarde wordt geëvalueerd true
. De reden hiervoor is dat stage2
het wordt overgeslagen als reactie op stage1
annuleren.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
steps:
- script: echo 2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
Taakvoorbeeld 1
In de volgende YAML-pijplijn is de taak B
standaard afhankelijk van de taak A
, maar de taak B
heeft een condition
set die moet worden uitgevoerd wanneer de bronbranch zich bevindt main
. Als u een build op de vertakking in de wachtrij zet en deze annuleert terwijl de main
taak wordt uitgevoerd, wordt de taak A
B
nog steeds uitgevoerd, omdat eq(variables['Build.SourceBranch'], 'refs/heads/main')
dit wordt geëvalueerd true
.
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo step 2.1
Als u wilt dat de taak alleen wordt uitgevoerd wanneer de taak B
A
slaagt en de buildbron de main
vertakking is, moet u condition
dit zijn and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
.
Taakvoorbeeld 2
In de volgende pijplijn is de taak B
standaard afhankelijk van de taak A
. Als u een build in de wachtrij op de vertakking zet en deze annuleert terwijl de main
taak wordt uitgevoerd, wordt de taak A
B
niet uitgevoerd, ook al heeft de stap een condition
die resulteert in true
.
De reden hiervoor is dat de taak B
de standaardwaarde condition: succeeded()
heeft, die evalueert false
wanneer de taak A
wordt geannuleerd. Daarom wordt de taak B
overgeslagen en worden de stappen niet uitgevoerd.
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
steps:
- script: echo step 2.1
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main', succeeded())
Stapvoorbeeld
U kunt ook voorwaarden voor stappen hebben.
In de volgende pijplijn heeft stap 2.3 een condition
set die moet worden uitgevoerd wanneer de bronbranch zich bevindt main
. Als u een build in de wachtrij op de main
vertakking zet en deze annuleert terwijl stap 2.1 of 2.2 wordt uitgevoerd, wordt stap 2.3 nog steeds uitgevoerd, omdat eq(variables['Build.SourceBranch'], 'refs/heads/main')
dit true
wordt geëvalueerd.
steps:
- script: echo step 2.1
- script: echo step 2.2; sleep 30
- script: echo step 2.3
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
Voorwaarde-instellingen
In de volgende tabel ziet u voorbeeldinstellingen condition
voor het produceren van verschillende resultaten.
Notitie
Release.Artifacts.{artifact-alias}.SourceBranch
is equivalent aan Build.SourceBranch
.
Gewenst resultaat | Voorbeeldvoorwaarde-instelling |
---|---|
Voer uit als de bronbranch main is, zelfs als de bovenliggende of vorige fase, taak of stap is mislukt of is geannuleerd. | eq(variables['Build.SourceBranch'], 'refs/heads/main') |
Voer uit als de bronbranch main is en de bovenliggende of vorige fase, taak of stap is geslaagd. | and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) |
Voer uit als de bronbranch niet de hoofd- of vorige fase, taak of stap is voltooid. | and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main')) |
Uitvoeren voor vertakkingen van gebruikersonderwerp, als de bovenliggende of voorgaande fase, taak of stap is geslaagd. | and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/')) |
Wordt uitgevoerd voor CI-builds (continue integratie), als de bovenliggende of vorige fase, taak of stap is geslaagd. | and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')) |
Voer uit als de build is geactiveerd door een vertakkingsbeleid voor een pull-aanvraag en de bovenliggende of vorige fase, taak of stap is mislukt. | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
Uitvoeren voor een geplande build, zelfs als de bovenliggende of vorige fase, taak of stap is mislukt of is geannuleerd. | eq(variables['Build.Reason'], 'Schedule') |
Voer uit als een variabele is ingesteld op true, zelfs als de bovenliggende of vorige fase, taak of stap is mislukt of is geannuleerd. | eq(variables['System.debug'], true) |
Notitie
U kunt een voorwaarde instellen die moet worden uitgevoerd als een variabele null is (lege tekenreeks). Omdat alle variabelen worden behandeld als tekenreeksen in Azure Pipelines, is een lege tekenreeks gelijk aan null
in de volgende pijplijn:
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
Parameters in voorwaarden
Parameteruitbreiding vindt plaats voordat voorwaarden worden overwogen. Wanneer u daarom een parameter declareert in dezelfde pijplijn als een voorwaarde, kunt u de parameter insluiten in de voorwaarde. Het script in de volgende YAML wordt uitgevoerd omdat parameters.doThing
dit waar is.
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
In condition
de voorgaande pijplijn worden twee functies gecombineerd: succeeded()
en ${{ eq(parameters.doThing, true) }}
. De succeeded()
functie controleert of de vorige stap is geslaagd. De succeeded()
functie retourneert true
omdat er geen vorige stap is.
De ${{ eq(parameters.doThing, true) }}
functie controleert of de doThing
parameter gelijk is aan true
. Omdat de standaardwaarde doThing
is ingesteld true
, retourneert true
de voorwaarde standaard, tenzij de pijplijn een andere waarde instelt.
Sjabloonparameters in voorwaarden
Wanneer u een parameter doorgeeft aan een sjabloon, moet u de waarde van de parameter instellen in uw sjabloon of templateContext gebruiken om de parameter door te geven aan de sjabloon.
Het volgende parameters.yml bestand declareert bijvoorbeeld de doThing
parameter en de standaardwaarde:
# parameters.yml
parameters:
- name: doThing
default: true # value passed to the condition
type: boolean
jobs:
- job: B
steps:
- script: echo I did a thing
condition: ${{ eq(parameters.doThing, true) }}
De pijplijncode verwijst naar de parameters.yml-sjabloon . De uitvoer van de pijplijn komt I did a thing
omdat de parameter doThing
waar is.
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
Zie de sjabloongebruiksreferentie voor meer voorbeelden van sjabloonparameters.
Taakuitvoervariabelen die worden gebruikt in volgende taakvoorwaarden
U kunt een variabele beschikbaar maken voor toekomstige taken en deze opgeven in een voorwaarde. Variabelen die beschikbaar zijn voor toekomstige taken moeten worden gemarkeerd als uitvoervariabelen met meerdere taken, isOutput=true
zoals in de volgende code:
jobs:
- job: Foo
steps:
- bash: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
name: DetermineResult
- job: Bar
dependsOn: Foo
condition: eq(dependencies.Foo.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
steps:
- script: echo "Job Foo ran and doThing is Yes."
Variabelen die zijn gemaakt in een stap die wordt gebruikt in de volgende stapvoorwaarden
U kunt een variabele maken die beschikbaar is voor toekomstige stappen die moeten worden opgegeven in een voorwaarde. Variabelen die zijn gemaakt op basis van stappen zijn standaard beschikbaar voor toekomstige stappen en hoeven niet te worden gemarkeerd als uitvoervariabelen voor meerdere taken.
Er zijn enkele belangrijke dingen die u moet weten over bereikvariabelen die zijn gemaakt op basis van stappen.
- Variabelen die zijn gemaakt in een stap in een taak, zijn gericht op de stappen in dezelfde taak.
- Variabelen die in een stap zijn gemaakt, zijn alleen beschikbaar in volgende stappen als omgevingsvariabelen.
- Variabelen die in een stap zijn gemaakt, kunnen niet worden gebruikt in de stap die deze definieert.
In het volgende voorbeeld ziet u het maken van een pijplijnvariabele in een stap en het gebruik van de variabele in de voorwaarde en het script van een volgende stap.
steps:
# This step creates a new pipeline variable: doThing. This variable is available to subsequent steps.
- bash: |
echo "##vso[task.setvariable variable=doThing]Yes"
displayName: Step 1
# This step is able to use doThing, so it uses doThing in its condition
- script: |
# Access the variable from Step 1 as an environment variable.
echo "Value of doThing (as DOTHING env var): $DOTHING."
displayName: Step 2
condition: and(succeeded(), eq(variables['doThing'], 'Yes')) # or and(succeeded(), eq(variables.doThing, 'Yes'))
Veelgestelde vragen
Hoe kan ik een taak activeren als een vorige taak problemen heeft gegeven?
U kunt het resultaat van de vorige taak in een voorwaarde gebruiken. In de volgende YAML kan de voorwaarde eq(dependencies.A.result,'SucceededWithIssues')
bijvoorbeeld worden uitgevoerd omdat de taak B
A
is geslaagd met problemen.
jobs:
- job: A
displayName: Job A
continueOnError: true # next job starts even if this one fails
steps:
- script: echo Job A ran
- script: exit 1
- job: B
dependsOn: A
condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job
displayName: Job B
steps:
- script: echo Job B ran
Ik heb mijn build geannuleerd, maar het wordt nog steeds uitgevoerd. Waarom?
U kunt dit probleem ondervinden als een voorwaarde die is geconfigureerd in een fase geen functie voor taakstatuscontrole bevat. U kunt het probleem oplossen door een functie voor taakstatuscontrole toe te voegen aan de voorwaarde.
Als u een taak annuleert terwijl deze zich in de wachtrijfase bevindt, maar niet wordt uitgevoerd, wordt de hele taak geannuleerd, inclusief alle andere fasen. Zie Resultaten van voorwaarde als een build eerder in dit artikel wordt geannuleerd voor meer informatie.