Ange villkor

Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019

Du kan ange under vilka villkor varje fas, jobb eller steg körs. Som standard körs ett jobb eller en fas om det inte är beroende av något annat jobb eller steg, eller om alla jobb eller faser som det är beroende av har slutförts och lyckats. Detta omfattar inte bara direkta beroenden, utan även deras beroenden, som beräknas rekursivt. Som standard körs ett steg om inget i jobbet har misslyckats ännu och steget omedelbart före det har slutförts. Du kan anpassa det här beteendet genom att tvinga en fas, ett jobb eller ett steg att köra även om ett tidigare beroende misslyckas eller genom att ange ett anpassat villkor.

Du kan ange villkor enligt vilka ett steg, ett jobb eller en fas ska köras.

  • Endast när alla tidigare direkta och indirekta beroenden med samma agentpool har lyckats. Dessa faser eller jobb körs samtidigt om du har olika agentpooler. Detta är standardvärdet om det inte finns något villkor i YAML.

  • Även om ett tidigare beroende har misslyckats, såvida inte körningen avbröts. Använd succeededOrFailed() i YAML för det här villkoret.

  • Även om ett tidigare beroende har misslyckats, även om körningen avbröts. Använd always() i YAML för det här villkoret.

  • Endast när ett tidigare beroende har misslyckats. Använd failed() i YAML för det här villkoret.

  • Anpassade villkor

Som standard körs steg, jobb och steg om alla direkta och indirekta beroenden har lyckats. Det är som om du angav "condition: succeeded()" (se statusfunktionen lyckades).

jobs:
- job: Foo

  steps:
  - script: echo Hello!
    condition: always() # this step will always run, even if the pipeline is canceled

- job: Bar
  dependsOn: Foo
  condition: failed() # this job will only run if Foo fails

Du kan också använda variabler under förhållanden.

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)

Villkor utvärderas för att avgöra om ett steg, ett jobb eller ett steg ska startas. Det innebär att inget som beräknas vid körning i den arbetsenheten kommer att vara tillgängligt. Om du till exempel har ett jobb som anger en variabel med ett körningsuttryck med hjälp av $[ ] syntax, kan du inte använda variabeln i ditt anpassade villkor.

YAML stöds inte i TFS.

Kommentar

När du anger din egen condition egenskap för ett steg/jobb/steg skriver du över standardvärdet condition: succeeded(). Detta kan leda till att steget/jobbet/steget körs även om bygget avbryts. Se till att du tar hänsyn till tillståndet för den överordnade fasen/jobbet när du skriver dina egna villkor.

Aktivera ett anpassat villkor

Om de inbyggda villkoren inte uppfyller dina behov kan du ange anpassade villkor.

Villkor skrivs som uttryck i YAML-pipelines. Agenten utvärderar uttrycket som börjar med den innersta funktionen och arbetar sig ut. Slutresultatet är ett booleskt värde som avgör om uppgiften, jobbet eller fasen ska köras eller inte. I artikeln uttryck finns en fullständig guide till syntaxen.

Gör något av dina villkor att uppgiften kan köras även efter att bygget har avbrutits av en användare? I så fall anger du ett rimligt värde för tidsgränsen för att avbryta så att den här typen av uppgifter har tillräckligt med tid för att slutföras när användaren har avbrutit en körning.

Pipelinebeteende när bygget avbryts

När ett bygge avbryts betyder det inte att alla faser, jobb eller steg slutar köras. Beslutet beror på fasen, jobbet eller steget conditions som du angav och vid vilken tidpunkt i pipelinens körning du avbröt bygget.

Om villkoret inte tar hänsyn till tillståndet för den överordnade delen av din fas/ditt jobb/steg, så körs om villkoret utvärderas till true, körs ditt stadium, jobb eller steg, även om dess överordnade objekt har avbrutits. Om dess överordnade överordnad hoppas över körs inte ditt steg, jobb eller steg.

Låt oss titta på några exempel.

I den här pipelinen är som standard stage2 beroende av stage1 och stage2 har en condition uppsättning. stage2 körs bara när källgrenen är main.

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

Om du köar ett bygge på grenen main och avbryter den medan stage1 den körs stage2 , körs den fortfarande eftersom eq(variables['Build.SourceBranch'], 'refs/heads/main') utvärderas till true.

I den här pipelinen stage2 beror på stage1. Jobbet B har en condition uppsättning för det.

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

Om du köar ett bygge på grenen main och avbryter den medan stage1 den körs stage2, körs den inte , även om den innehåller ett jobb B vars villkor utvärderas till true. Orsaken är att stage2 har standardvärdet condition: succeeded(), som utvärderas till false när stage1 avbryts. stage2 Därför hoppas över och inget av dess jobb körs.

Anta att du har följande YAML-pipeline. Observera att som standard stage2 är beroende av stage1 och som script: echo 2 har en condition uppsättning för den.

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')

Om du köar ett bygge på grenen main och avbryter den medan stage1 den körs stage2, körs den inte , även om den innehåller ett steg i jobbet B vars villkor utvärderas till true. Orsaken är att stage2 hoppas över som svar på att stage1 avbrytas.

Om du vill förhindra att faser, jobb eller steg med conditions körs när en version avbryts bör du överväga deras överordnade tillstånd när du skriver conditions. Mer information finns i Jobbstatusfunktioner.

Exempel

Kör för huvudgrenen, även om den avbryts, även om den misslyckas

eq(variables['Build.SourceBranch'], 'refs/heads/main')

Kör för huvudgrenen om det lyckas

and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Kör om grenen inte är huvudgrenen om den lyckas

and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))

Kör för användarämnesgrenar om det lyckas

and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))

Kör för kontinuerlig integrering (CI) om det lyckas

and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))

Kör om bygget körs av en grenprincip för en pull-begäran, om det misslyckas

and(failed(), eq(variables['Build.Reason'], 'PullRequest'))

Kör om bygget är schemalagt, även om det misslyckas, även om det avbryts

eq(variables['Build.Reason'], 'Schedule')

Release.Artifacts. {artifact-alias}. SourceBranch motsvarar Build.SourceBranch.

Kör alltid om en variabel är inställd på true, även om den avbryts, även om den misslyckas

eq(variables['System.debug'], true)

Kör om en variabel är null (tom sträng)

Eftersom alla variabler behandlas som strängar i Azure Pipelines motsvarar null en tom sträng i den här pipelinen.

variables:
- name: testEmpty
  value: ''

jobs:
  - job: A
    steps:
    - script: echo testEmpty is blank
    condition: eq(variables.testEmpty, '')

Använda en mallparameter som del av ett villkor

När du deklarerar en parameter i samma pipeline som du har ett villkor sker parameterexpansionen innan villkoret utvärderats. I det här fallet kan du bädda in parametrar inuti villkor. Skriptet i den här YAML-filen körs eftersom parameters.doThing det är sant.

I condition pipelinen kombineras två funktioner: succeeded() och eq('${{ parameters.doThing }}', true). Funktionen succeeded() kontrollerar om föregående steg lyckades. Funktionen succeeded() returnerar true eftersom det inte fanns något föregående steg.

Funktionen eq('${{ parameters.doThing }}', true) kontrollerar om parametern doThing är lika med true. Eftersom standardvärdet för doThing är sant returnerar villkoret true som standard om inte ett annat värde anges i pipelinen.

Fler exempel på mallparameter finns i Malltyper och användning.

parameters:
- name: doThing
  default: true
  type: boolean

steps:
- script: echo I did a thing
  condition: ${{ eq(parameters.doThing, true) }}

När du skickar en parameter till en mall måste du ange parameterns värde i mallen eller använda templateContext för att skicka egenskaper till mallar.

# 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) }}
# azure-pipeline.yml
parameters:
- name: doThing
  default: true 
  type: boolean

trigger:
- none

extends:
  template: parameters.yml

Utdata från den här pipelinen beror I did a thing på att parametern doThing är sann.

Använda utdatavariabeln från ett jobb i ett villkor i ett efterföljande jobb

Du kan göra en variabel tillgänglig för framtida jobb och ange den i ett villkor. Variabler som är tillgängliga för framtida jobb måste markeras som utdatavariabler för flera jobb med hjälp av isOutput=true.

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."

Använda pipelinevariabeln som skapats från ett steg i ett villkor i ett efterföljande steg

Du kan göra en variabel tillgänglig för framtida steg och ange den i ett villkor. Som standard är variabler som skapats från ett steg tillgängliga för framtida steg och behöver inte markeras som utdatavariabler för flera jobb med hjälp av isOutput=true.

Det finns några viktiga saker att notera när det gäller ovanstående metod och omfång:

  • Variabler som skapas i ett steg i ett jobb begränsas till stegen i samma jobb.
  • Variabler som skapas i ett steg är endast tillgängliga i efterföljande steg som miljövariabler.
  • Variabler som skapas i ett steg kan inte användas i steget som definierar dem.

Nedan visas ett exempel på hur du skapar en pipelinevariabel i ett steg och använder variabeln i ett efterföljande stegs villkor och skript.

steps:

# This step creates a new pipeline variable: doThing. This variable will be available to subsquent steps.
- bash: |
    echo "##vso[task.setvariable variable=doThing]Yes"
  displayName: Step 1

# This step is able to use doThing, so it uses it in its condition
- script: |
    # You can 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'))

Vanliga frågor

Hur utlöser jag ett jobb om ett tidigare jobb avslutats med problem?

Du kan använda resultatet från föregående jobb. I den här YAML-filen tillåter villkoret eq(dependencies.A.result,'SucceededWithIssues') till exempel att jobbet körs eftersom jobb A lyckades med problem.

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

Jag avbröt min version, men den körs fortfarande. Vad händer?

Det här problemet uppstår om villkoret som har konfigurerats i fasen inte innehåller någon funktion för jobbstatuskontroll. Lös problemet genom att lägga till en funktion för jobbstatuskontroll i villkoret. Om du avbryter ett jobb medan det finns i kön, men inte körs, avbryts hela jobbet, inklusive alla andra steg.

Läs mer om en pipelines beteende när en version avbryts.