Delen via


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 truegeë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 stage1van, 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 truewordt 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 stage1van 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 truewordt 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=truezoals 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.