Dela via


Tillstånd för rörledning

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020

Den här artikeln beskriver de olika villkor som gör att ett Azure Pipelines-steg, jobb eller steg kan köras och hur du anger dessa villkor i en YAML-pipelinedefinition.

Kommentar

I den här artikeln beskrivs YAML-pipelinefunktioner. För klassiska pipelines kan du ange vissa villkor där uppgifter eller jobb körs i kontrollalternativ för varje uppgift och i ytterligare alternativ för ett jobb i en versionspipeline.

Villkorar en fas, ett jobb eller ett steg som körs under

Som standard körs ett pipelinejobb eller en fas om det inte är beroende av något annat jobb eller stadium, eller om alla dess beroenden har slutförts och lyckats. Beroendekravet gäller för direkta beroenden och deras indirekta beroenden, som beräknas rekursivt.

Som standard körs ett steg om inget i jobbet ännu har misslyckats och steget omedelbart före det har slutförts. Mer kontext om steg, jobb och steg finns i Viktiga begrepp för Azure Pipelines.

Du kan åsidosätta eller anpassa dessa standardbeteenden genom att ange en fas, ett jobb eller ett steg som ska köras även om eller bara om ett tidigare beroende misslyckas eller har ett annat resultat. Du kan också definiera anpassade villkor. I en YAML-pipelinedefinition använder condition du egenskapen för att ange villkor under vilka ett steg, ett jobb eller ett steg kan köras.

Kommentar

Villkor gäller för alla tidigare direkta och indirekta beroenden med samma agentpool. Faser eller jobb i olika agentpooler körs samtidigt.

Villkor som baseras på tidigare beroendestatus är:

  • Lyckades: Kör endast om alla tidigare beroenden lyckas. Det här beteendet är standard om inget villkor anges i YAML. Om du vill tillämpa det här villkoret anger du condition: succeeded().
  • Lyckades eller misslyckades: Kör även om ett tidigare beroende misslyckas, såvida inte körningen avbryts. Om du vill tillämpa det här villkoret anger du condition: succeededOrFailed().
  • Alltid: Kör även om ett tidigare beroende misslyckas, även om körningen avbryts. Om du vill tillämpa det här villkoret anger du condition: always().
  • Misslyckades: Kör endast när ett tidigare beroende misslyckas. Om du vill tillämpa det här villkoret anger du condition: failed().

Viktigt!

När du anger en condition egenskap för en fas, ett jobb eller ett steg skriver du över standardvillkoret. Ditt steg, jobb eller steg kan köras även om bygget avbryts. Se till att dina villkor tar hänsyn till tillståndet för den överordnade fasen eller jobbet.

Villkorsexempel

Följande YAML-exempel visar villkoren always() och failed() . Den första skriptuppgiften i jobb 1 har ett always villkor, så den körs även om beroenden misslyckas eller om bygget avbryts. I den andra skriptuppgiften tvingar exit job1job1 jobbet att misslyckas.

Pipelinesteg körs sekventiellt som standard, men jobb kan köras parallellt. Du kan använda egenskapen dependsOn för att explicit definiera beroenden mellan faser eller jobb.

Om du vill ange villkoren för ett jobb som är beroende av resultatet av ett annat jobb använder du dependsOn för att definiera beroendet. I följande exempel job2 beror på job1 och körs eftersom job1 misslyckas.

jobs:
- job: job1
  steps:
  - script: echo Hello!
    condition: always() # this step runs even if the build is canceled
  - script: |
      echo "This task will fail."
      exit job1 
- job: job2
  dependsOn: job1
  condition: failed() # this job runs only if job1 fails

Kommentar

Du kan också använda Användargränssnittet för Azure Pipelines för att köra beroende steg manuellt när den överordnade fasen misslyckas. Mer information finns i Köra underordnade faser när överordnad fas misslyckas.

Anpassade villkor

Om de inbyggda villkoren inte uppfyller dina behov kan du ange anpassade villkor som uttryck i YAML-pipelinedefinitioner.

Agenten utvärderar uttrycket som börjar med den innersta funktionen och fortsätter utåt. Slutresultatet är ett booleskt värde som avgör om steget, jobbet eller steget ska köras eller inte. En fullständig guide till syntaxen finns i Uttryck.

Viktigt!

Villkor utvärderas för att avgöra om en etapp, ett jobb eller ett steg ska startas. Därför är inget som beräknas under körningen av ett steg, jobb eller steg tillgängligt att använda inom samma fas, jobb eller steg. Om du till exempel anger en variabel i ett jobb med ett körningsuttryck med $[ ] syntax, kan du inte använda variabeln i villkor i jobbet.

Variabler i villkor

Du kan ange pipelinevariabler och använda dem under förhållanden. Följande pipeline anger en isMain variabel och använder den i ett villkor som endast kör steg B när byggkällgrenen är main.

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)

Du kan ange att ett villkor ska köras om en variabel är null eller en tom sträng. Alla variabler behandlas som strängar i Azure Pipelines, så en tom sträng motsvarar null i följande pipeline:

variables:
- name: testEmpty
  value: ''

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

Jobbutdatavariabler som används i andra jobbvillkor

Du kan skapa en variabel i ett jobb som andra jobb i samma fas kan ange i villkor. Variabler som är tillgängliga för beroende jobb måste markeras som utdatavariabler för flera jobb med hjälp isOutput=trueav , som i följande kod:

jobs:
- job: A
  steps:
  - bash: |
      echo "This is job A."
      echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
    name: DetermineResult
- job: B
  dependsOn: A
  condition: eq(dependencies.A.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
  steps:
  - script: echo "Job A ran and doThing is Yes."

Stegvariabler som används i efterföljande stegvillkor

Du kan skapa en variabel i ett steg som framtida steg i samma jobb kan ange i villkor. Variabler som skapas från steg är tillgängliga för framtida steg i jobbet som standard och behöver inte markeras som utdatavariabler för flera jobb.

Variabler som skapas i ett steg i ett jobb har följande begränsningar:

  • Är begränsade till stegen i samma jobb.
  • Är endast tillgängliga i efterföljande steg som miljövariabler.
  • Det går inte att använda i samma steg som definierar dem.

I följande exempel skapas en pipelinevariabel i ett steg och variabeln används i ett senare stegs skriptvillkor.

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

Villkorsinställningar för olika resultat

I följande tabell visas condition inställningar för att skapa olika önskade resultat.

Önskat resultat Exempel på villkorsinställning
Kör om källgrenen är main, även om det överordnade eller föregående steget, jobbet eller steget misslyckades eller avbröts. eq(variables['Build.SourceBranch'], 'refs/heads/main')
Kör om källgrenen är main och det överordnade eller föregående steget, jobbet eller steget lyckades. and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
Kör om källgrenen inte mainär , och det överordnade eller föregående steget, jobbet eller steget lyckades. and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
Kör för grenar user om det överordnade eller föregående steget, jobbet eller steget lyckades. and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
Kör för kontinuerlig integrering (CI) om det överordnade eller föregående steget, jobbet eller steget lyckades. and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
Kör om en pull-begäran utlöste bygget och det överordnade eller föregående steget, jobbet eller steget misslyckades. and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
Kör för en schemalagd version, även om det överordnade eller föregående steget, jobbet eller steget misslyckades eller avbröts. eq(variables['Build.Reason'], 'Schedule')
Kör om variabeln System.debug är inställd på true, även om det överordnade eller föregående steget, jobbet eller steget misslyckades eller avbröts. eq(variables['System.debug'], true)

Kommentar

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

Villkorsresultat när en version avbryts

Att avbryta ett bygge innebär inte att alla dess faser, jobb och steg slutar att köras. Vilka jobb, steg eller steg som slutar köras beror på de villkor som du angav och vid vilken tidpunkt pipelinekörningen avbröt du bygget. Om en fas, ett jobb eller ett stegs överordnade objekt hoppas över, körs inte fasen, jobbet eller steget, oavsett villkor.

En etapp, ett jobb eller ett steg körs när dess villkor utvärderas till true. Om ett villkor inte tar hänsyn till tillståndet för aktivitetens överordnade kan aktiviteten köras även om dess överordnade objekt avbryts. Om du vill styra om jobb, steg eller steg körs när en version avbryts, inkluderar du en funktion för jobbstatuskontroll i dina villkor.

Om du avbryter en version medan den är i köfasen men inte körs ännu avbryts hela körningen, inklusive alla andra steg.

Kommentar

Om något av dina villkor gör det möjligt för aktiviteter att köras även efter att bygget har avbrutits anger du ett värde för tidsgränsen avbryts som ger tillräckligt med tid för aktiviteterna att slutföras när körningen har avbrutits.

Exempel på scenvillkorsresultat

I följande exempel visas resultatet av olika villkor som angetts i faser när bygget avbryts.

Stadieexempel 1

I följande pipeline skulle som standard stage2 vara beroende av stage1 att slutföras. Har dock stage2 en condition uppsättning som ska köras när källgrenen är main, oavsett stage1 status.

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

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

Etapp exempel 2

I följande pipeline är som standard stage2 beroende av stage1 att slutföras. Jobbet B i stage2 har en condition uppsättning som ska köras när källgrenen är main.

Om du köar ett bygge på grenen main och avbryter den medan stage1 den körs och stage2 dess jobb inte körs alls, även om fasen innehåller ett jobb vars villkor utvärderas till true.

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

Stegexempel 3

I följande pipeline är som standard stage2 beroende av stage1 att slutföras. Steget inuti jobbet B inom har en stage2 uppsättning som ska köras när källgrenen är conditionmain .

Om du köar ett bygge på grenen main och avbryter den medan stage1 den körs och stage2 jobbet B inte körs alls, även om jobbet B innehåller ett steg vars villkor utvärderas till true. Stage2 hoppas över helt eftersom stage1 avbröts.

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

Exempel på jobbvillkorsresultat

I följande exempel visas resultatet av olika villkor som angetts för jobb när bygget avbryts.

Jobbexempel 1

I följande YAML-pipeline beror jobbkörningen B på att jobbet A körs. Jobbet B har också en condition uppsättning som ska köras när källgrenen är main.

Om du köar ett bygge på grenen main och avbryter byggprocessen medan jobbet A körs, fortsätter jobbet B att köras eftersom värdet av condition: eq(variables['Build.SourceBranch'], 'refs/heads/main') blir 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

Om du bara vill att jobbet B ska köras när jobbet A lyckas och byggkällan är mainmåste du ange condition till and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')).

Jobbexempel 2

I följande YAML-pipeline är jobbet B beroende av att jobbet A lyckas. Jobbet B har en condition uppsättning som ska köras när jobbet A lyckas och byggkällans gren är main.

Om du köar ett bygge på grenen main och avbryter det medan jobbet A körs körs inte jobbet B , även om det har ett condition som utvärderas till true. Villkoret för jobbet B utvärderas till false eftersom jobbet A inte lyckades. Därför hoppas jobbet B och dess steg över.

jobs:
- job: A
  steps:
  - script: sleep 30
- job: B
  dependsOn: A 
  steps:
    - script: echo step 2.1
  condition: and(eq(variables['Build.SourceBranch'], 'refs/heads/main'), succeeded())

Exempel på stegvillkorsutfall

Du kan också ange villkor för steg. I följande pipeline har steg 2.3 en condition uppsättning som ska köras när källgrenen är main.

Om du köar en byggning på grenen main och avbryter den medan steg 2.1 eller 2.2 körs, körs steg 2.3 ändå eftersom eq(variables['Build.SourceBranch'], 'refs/heads/main') utvärderas till true.

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

Parametrar i villkor

Du kan använda parametrar under förhållanden. Parameterexpansion sker innan pipelinen körs och ersätter värden som omges av ${{ }} med parametervärdena literal. Eftersom parameterexpansion sker före villkorsutvärdering kan du deklarera en parameter i en pipeline och bädda in parametern i alla villkor i pipelinen.

I condition följande exempel kombineras två funktioner: succeeded() och ${{ eq(parameters.doThing, true) }}. Funktionen succeeded() kontrollerar om föregående steg lyckades. Den här funktionen returnerar true också om det inte finns något föregående steg.

Funktionen ${{ eq(parameters.doThing, true) }} kontrollerar om parametern doThing är lika med true. Skriptsteget i följande exempel körs eftersom det inte fanns något föregående steg och parameters.doThing är true som standard.

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

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

Mallparametrar i villkor

När du skickar en parameter till en pipelinemall kan du ange parameterns värde i mallfilen eller använda templateContext för att skicka parametern till mallen.

Följande parameters.yml mallfil deklarerar parametern doThing med standardvärdet true och använder parametern i ett jobbvillkor.

# parameters.yml
parameters:
- name: doThing
  default: true
  type: boolean

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

Följande azure-pipelines.yml pipelinedefinition refererar till jobbet i parameters.yml-mallfilen. Utdata från pipelinen beror I did a thing på att parametern doThing är true som standard.

# azure-pipelines.yml

extends:
  template: parameters.yml

Fler exempel på mallparameter finns i mallanvändningsreferensen.

Vanliga frågor

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

Du kan använda resultatet av det tidigare jobbet i ett villkor. I följande YAML anger villkoret eq(dependencies.A.result,'SucceededWithIssues') att jobbet B ska köras efter att jobbet A lyckades med problem.

jobs:
- job: A
  steps:
  - script: echo Job A ran
- job: B
  dependsOn: A
  condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job 
  steps:
  - script: echo Job A had issues

Varför körs mitt bygge fortfarande när jag har avbrutit det?

Du kan uppleva det här problemet om ett villkor som konfigurerats i en fas inte innehåller någon funktion för jobbstatuskontroll. Lös problemet genom att lägga till en funktion för jobbstatuskontroll i villkoret. Mer information finns i Villkorsresultat när en version avbryts.