Sdílet prostřednictvím


Podmínky kanálu

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

Tento článek popisuje podmínky, za kterých se spouští fáze, úloha nebo krok Služby Azure Pipelines a jak určit různé podmínky. Další kontext fází, úloh a kroků najdete v tématu Klíčové koncepty pro Azure Pipelines.

  • Ve výchozím nastavení se úloha nebo fáze spustí, pokud nezávisí na žádné jiné úloze nebo dílčí fázi, nebo pokud jsou všechny její závislosti dokončené a úspěšné. Tento požadavek se vztahuje nejen na přímé závislosti, ale i na jejich nepřímé závislosti vypočítané rekurzivně.

  • Ve výchozím nastavení se krok spustí, pokud v úloze ještě nic selhalo a krok bezprostředně před dokončením.

Toto chování můžete přepsat nebo přizpůsobit vynucením spuštění fáze, úlohy nebo kroku, a to i v případě, že předchozí závislost selže, nebo zadáním vlastní podmínky.

Poznámka:

Tento článek popisuje možnosti kanálu YAML. U klasických kanálů můžete zadat určité podmínky, za kterých se úlohy nebo úlohy spouštějí v možnostech řízení jednotlivých úloh, a v dalších možnostech úlohy v kanálu verze.

Podmínky, za kterých se spouští fáze, úloha nebo krok

V definici kanálu YAML můžete zadat následující podmínky, za kterých se spouští fáze, úloha nebo krok:

  • Pouze pokud všechny předchozí přímé a nepřímé závislosti se stejným fondem agentů proběhnou úspěšně. Pokud máte různé fondy agentů, tyto fáze nebo úlohy se spouštějí souběžně. Tato podmínka je výchozí, pokud v YAML není nastavena žádná podmínka.

  • I když předchozí závislost selže, pokud se spuštění nezruší. Použije succeededOrFailed() se v YAML pro tuto podmínku.

  • I v případě selhání předchozí závislosti a i v případě zrušení spuštění. Použije always() se v YAML pro tuto podmínku.

  • Pouze v případě, že předchozí závislost selže. Použije failed() se v YAML pro tuto podmínku.

  • Vlastní podmínky.

Ve výchozím nastavení se fáze, úlohy a kroky spouštějí, pokud jsou všechny přímé a nepřímé závislosti úspěšné. Tento stav je stejný jako určení condition: succeeded(). Další informace najdete v článku o úspěšné stavové funkci.

Když zadáte condition vlastnost pro fázi, úlohu nebo krok, přepíšete výchozí condition: succeeded(). Zadání vlastních podmínek může způsobit spuštění fáze, úlohy nebo kroku i v případě, že je sestavení zrušeno. Ujistěte se, že podmínky, které napíšete, berou v úvahu stav nadřazené fáze nebo úlohy.

Následující příklad YAML ukazuje always() podmínky a failed() ujednání. Krok v první úloze se spustí i v případě selhání závislostí nebo zrušení sestavení. Druhá úloha se spustí jenom v případě, že první úloha selže.

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

Můžete také nastavit a používat proměnné v podmínkách. Následující příklad nastaví a používá proměnnou isMain k určení main jako 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)

Důležité

Podmínky se vyhodnocují a určují, jestli se má spustit fáze, úloha nebo krok. Proto není k dispozici nic vypočítané za běhu uvnitř této jednotky práce. Pokud máte například úlohu, která nastaví proměnnou pomocí výrazu modulu runtime se $[ ] syntaxí, nemůžete tuto proměnnou použít ve vlastní podmínce v této úloze.

Vlastní podmínky

Pokud předdefinované podmínky nevyhovují vašim potřebám, můžete zadat vlastní podmínky. Podmínky zapisujete jako výrazy v definicích kanálu YAML.

Agent vyhodnotí výraz začínající nejvnitřnější funkcí a pokračuje směrem ven. Konečný výsledek je logická hodnota, která určuje, zda má být úkol, úloha nebo fáze spuštěna. Úplný průvodce syntaxí najdete v tématu Výrazy.

Pokud některé z vašich podmínek umožní spuštění úlohy i po zrušení sestavení, zadejte přiměřenou hodnotu pro vypršení časového limitu zrušení, aby tyto úkoly měly dostatek času na dokončení po zrušení spuštění uživatelem.

Výsledky podmínky při zrušení sestavení

Zrušení sestavení neznamená, že všechny její fáze, úlohy nebo kroky přestanou běžet. Které fáze, úlohy nebo kroky se zastaví, závisí na zadaných podmínkách a v jakém okamžiku spuštění kanálu jste zrušili sestavení. Pokud je nadřazená fáze, úloha nebo krok vynechána, úloha se nespustí bez ohledu na její podmínky.

Fáze, úloha nebo krok se spustí pokaždé, když se její podmínky vyhodnotí jako true. Pokud vaše podmínka nebere v úvahu stav nadřazeného úkolu, může se úkol spustit i v případě, že je jeho nadřazený objekt zrušen. Pokud chcete řídit, jestli se fáze, úlohy nebo kroky s podmínkami spouští při zrušení sestavení, nezapomeňte do podmínek zahrnout funkci kontroly stavu úlohy.

Následující příklady ukazují výsledky různých podmínek nastavených ve fázích, úlohách nebo krocích při zrušení sestavení.

Příklad fáze 1

V následujícím kanálu by ve výchozím nastavení stage2 závisel na stage1, ale stage2 má nastavenou condition možnost spustit vždy, když zdrojová větev je main, bez stage1 ohledu na stav.

Pokud ve větvi zařadíte sestavení main do fronty a zrušíte ho během stage1 běhu, stage2 stále se spustí, protože eq(variables['Build.SourceBranch'], 'refs/heads/main') se vyhodnotí jako 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

Příklad fáze 2

V následujícím kanálu stage2 závisí ve výchozím nastavení.stage1 Úloha B v stage2 condition sadě. Pokud sestavení main ve větvi zařadíte do fronty a zrušíte ho během stage1 běhu, nespustí se, stage2 i když obsahuje úlohu, jejíž podmínka se vyhodnotí jako true.

Důvodem je to, že stage2 má výchozí hodnotu condition: succeeded(), která se vyhodnotí jako false zrušená stage1 . stage2 Proto se přeskočí a nespustí se žádná z jejích úloh.

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

Příklad fáze 3

Ve výchozím nastavení stage2 závisí následující kanál a stage1krok uvnitř úlohy B má nastavenou condition sadu.

Pokud sestavení main ve větvi zařadíte do fronty a zrušíte ho během stage1 běhu, stage2 nespustí se, i když obsahuje krok v úloze B , jejíž podmínka se vyhodnotí jako true. Důvodem je to, že stage2 se v reakci na stage1 zrušení přeskočí.

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

Příklad úlohy 1

V následujícím kanálu B YAML úloha ve výchozím nastavení závisí na úloze A , ale úloha B je nastavená tak, aby se spustila condition vždy, když je mainzdrojová větev . Pokud ve větvi zařadíte sestavení main do fronty a zrušíte ho během běhu úlohy A , úloha B se stále spustí, protože eq(variables['Build.SourceBranch'], 'refs/heads/main') se vyhodnotí jako 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

Pokud chcete, aby úloha B běžela pouze v případě, že úloha A proběhne úspěšně a zdrojem sestavení je main větev, condition měla by být and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')).

Příklad úlohy 2

Úloha v následujícím kanálu B závisí ve výchozím nastavení na úloze A . Pokud zařadíte sestavení do main fronty ve větvi a zrušíte ho během běhu úlohy A , úloha B se nespustí, i když má její krok hodnotu, která se condition vyhodnotí jako true.

Důvodem je to, že úloha B má výchozí hodnotu condition: succeeded(), která se vyhodnotí jako false při zrušení úlohy A . B Úloha se proto přeskočí a žádný z jeho kroků se nespustí.

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

Příklad kroku

Můžete také mít podmínky pro kroky.

V následujícím kanálu je condition krok 2.3 nastavený tak, aby se spustil pokaždé, když je mainzdrojová větev . Pokud ve větvi zařadíte sestavení main do fronty a zrušíte ho, zatímco jsou spuštěné kroky 2.1 nebo 2.2, krok 2.3 stále běží, protože eq(variables['Build.SourceBranch'], 'refs/heads/main') se vyhodnotí jako 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')

Nastavení podmínky

Následující tabulka ukazuje ukázková condition nastavení pro vytváření různých výsledků.

Poznámka:

Release.Artifacts.{artifact-alias}.SourceBranch je ekvivalent Build.SourceBranch.

Požadovaný výsledek Příklad nastavení podmínky
Spusťte, pokud je zdrojová větev hlavní, a to i v případě, že nadřazená nebo předchozí fáze, úloha nebo krok selhaly nebo byly zrušeny. eq(variables['Build.SourceBranch'], 'refs/heads/main')
Spusťte, pokud je zdrojová větev hlavní a nadřazená nebo předchozí fáze, úloha nebo krok proběhly úspěšně. and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
Spusťte, pokud zdrojová větev není hlavní a nadřazená nebo předchozí fáze, úloha nebo krok proběhly úspěšně. and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
Spusťte větve tématu uživatele, pokud byla úspěšná nadřazená nebo předchozí fáze, úloha nebo krok. and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
Spusťte sestavení kontinuální integrace (CI), pokud byla úspěšná nadřazená nebo předchozí fáze, úloha nebo krok. and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
Spusťte, pokud se sestavení aktivovalo zásadami větve pro žádost o přijetí změn a nadřazená nebo předchozí fáze, úloha nebo krok selhaly. and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
Spusťte naplánované sestavení, a to i v případě, že nadřazená nebo předchozí fáze, úloha nebo krok selhaly nebo byly zrušeny. eq(variables['Build.Reason'], 'Schedule')
Spusťte, pokud je proměnná nastavená na hodnotu true, a to i v případě, že nadřazená nebo předchozí fáze, úloha nebo krok selhala nebo byla zrušena. eq(variables['System.debug'], true)

Poznámka:

Podmínku můžete nastavit tak, aby se spustila, pokud má proměnná hodnotu null (prázdný řetězec). Vzhledem k tomu, že všechny proměnné jsou v Azure Pipelines považovány za řetězce, je prázdný řetězec ekvivalentní null v následujícím kanálu:

variables:
- name: testEmpty
  value: ''

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

Parametry v podmínkách

Rozšíření parametru se provede před zvážením podmínek. Proto když deklarujete parametr ve stejném kanálu jako podmínka, můžete tento parametr vložit do podmínky. Skript v následujícím jazyce YAML se spustí, protože parameters.doThing je pravdivý.

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

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

Předchozí condition kanál kombinuje dvě funkce: succeeded() a ${{ eq(parameters.doThing, true) }}. Funkce succeeded() zkontroluje, jestli předchozí krok proběhl úspěšně. Funkce succeeded() se vrátí true , protože neexistuje žádný předchozí krok.

Funkce ${{ eq(parameters.doThing, true) }} zkontroluje, zda doThing je parametr roven true. Vzhledem k tomu, že výchozí hodnota je doThing true, podmínka se vrátí true ve výchozím nastavení, pokud kanál nenastaví jinou hodnotu.

Parametry šablony v podmínkách

Když předáte parametr šabloně, musíte buď nastavit hodnotu parametru v šabloně, nebo použít templateContext k předání parametru šabloně.

Například následující soubor parameters.yml deklaruje doThing parametr a výchozí hodnotu:

# 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) }}

Kód kanálu odkazuje na šablonu parameters.yml . Výstupem kanálu je I did a thing skutečnost, že parametr doThing je pravdivý.

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

trigger:
- none

extends:
  template: parameters.yml

Další příklady parametrů šablony najdete v referenčních informacích k použití šablony.

Výstupní proměnné úlohy použité v následných podmínkách úlohy

Proměnnou můžete zpřístupnit pro budoucí úlohy a zadat ji v podmínce. Proměnné, které jsou k dispozici pro budoucí úlohy, musí být označeny jako výstupní proměnné s více úlohami , isOutput=truejako v následujícím kódu:

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

Proměnné vytvořené v kroku použitém v dalších podmínkách kroku

Můžete vytvořit proměnnou, která je k dispozici pro budoucí kroky pro zadání v podmínce. Proměnné vytvořené z kroků jsou ve výchozím nastavení dostupné pro budoucí kroky a není nutné je označit jako výstupní proměnné s více úlohami.

Existuje několik důležitých věcí, které je potřeba si uvědomit o proměnných vytvořených z kroků.

  • Proměnné vytvořené v kroku v úloze jsou vymezeny na kroky ve stejné úloze.
  • Proměnné vytvořené v kroku jsou k dispozici v následných krocích pouze jako proměnné prostředí.
  • Proměnné vytvořené v kroku nelze použít v kroku, který je definuje.

Následující příklad ukazuje vytvoření proměnné kanálu v kroku a použití proměnné v podmínce a skriptu dalšího kroku.

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

Často kladené dotazy

Jak se dá aktivovat úloha, pokud předchozí úloha proběhla úspěšně, ale s problémy?

Výsledek předchozí úlohy můžete použít v podmínce. Například v následujícím jazyce YAML podmínka eq(dependencies.A.result,'SucceededWithIssues') umožňuje spuštění úlohy B , protože úloha A proběhla úspěšně s problémy.

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

Zrušil(a) jsem sestavení, ale pořád běží. Proč?

K tomuto problému můžete dojít, pokud podmínka nakonfigurovaná ve fázi neobsahuje funkci kontroly stavu úlohy. Pokud chcete tento problém vyřešit, přidejte do podmínky funkci kontroly stavu úlohy.

Pokud zrušíte úlohu v době, kdy je ve fázi fronty, ale není spuštěná, zruší se celá úloha včetně všech ostatních fází. Další informace naleznete v tématu Výsledky podmínky při zrušení sestavení dříve v tomto článku.