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 stage1
krok 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 main
zdrojová 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 main
zdrojová 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=true
jako 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.