Pipelinebedingungen
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
In diesem Artikel werden die Bedingungen beschrieben, unter denen eine Azure Pipelines-Phase, ein Auftrag oder ein Schritt ausgeführt wird und wie unterschiedliche Bedingungen angegeben werden. Weitere Kontexte zu Phasen, Aufträgen und Schritten finden Sie in den wichtigsten Konzepten für Azure-Pipelines.
Standardmäßig wird ein Auftrag oder eine Phase ausgeführt, wenn er nicht von einem anderen Auftrag oder einer anderen Phase abhängt oder ob alle Abhängigkeiten abgeschlossen und erfolgreich waren. Diese Anforderung gilt nicht nur für direkte Abhängigkeiten, sondern auch für ihre indirekten Abhängigkeiten, die rekursiv berechnet werden.
Standardmäßig wird ein Schritt ausgeführt, wenn noch nichts in seinem Auftrag fehlgeschlagen ist und der Schritt unmittelbar vor dem Vorgang abgeschlossen wurde.
Sie können dieses Verhalten außer Kraft setzen oder anpassen, indem Sie eine Phase, einen Auftrag oder einen Schritt erzwingen, auch wenn eine vorherige Abhängigkeit fehlschlägt, oder indem Sie eine benutzerdefinierte Bedingung angeben.
Hinweis
In diesem Artikel werden yaML-Pipelinefunktionen erläutert. Bei klassischen Pipelines können Sie einige Bedingungen angeben, unter denen Aufgaben oder Aufträge in den Steuerelementoptionen der einzelnen Aufgaben und in den zusätzlichen Optionen für einen Auftrag in einer Releasepipeline ausgeführt werden.
Bedingungen, unter denen eine Phase, ein Auftrag oder ein Schritt ausgeführt wird
In der Pipelinedefinitions-YAML können Sie die folgenden Bedingungen angeben, unter denen eine Phase, ein Auftrag oder ein Schritt ausgeführt wird:
Nur wenn alle vorherigen direkten und indirekten Abhängigkeiten mit demselben Agentpool erfolgreich sind. Wenn Sie über unterschiedliche Agentpools verfügen, werden diese Phasen oder Aufträge gleichzeitig ausgeführt. Diese Bedingung ist die Standardeinstellung, wenn keine Bedingung im YAML festgelegt ist.
Auch wenn eine vorherige Abhängigkeit fehlschlägt, es sei denn, die Ausführung wird abgebrochen. Verwenden Sie für diese Bedingung
succeededOrFailed()
in der YAML-Datei.Auch wenn eine vorherige Abhängigkeit fehlschlägt und auch dann, wenn die Ausführung abgebrochen wird. Verwenden Sie für diese Bedingung
always()
in der YAML-Datei.Nur wenn eine vorherige Abhängigkeit fehlschlägt. Verwenden Sie für diese Bedingung
failed()
in der YAML-Datei.
- Benutzerdefinierte Bedingungen.
Standardmäßig werden Phasen, Aufträge und Schritte ausgeführt, wenn alle direkten und indirekten Abhängigkeiten erfolgreich sind. Dieser Status ist identisch mit der Angabe condition: succeeded()
. Weitere Informationen finden Sie in der Statusfunktion "erfolgreich".
Wenn Sie eine Eigenschaft für eine condition
Phase, einen Auftrag oder einen Schritt angeben, überschreiben Sie die Standardeinstellung condition: succeeded()
. Die Angabe ihrer eigenen Bedingungen kann dazu führen, dass Ihre Phase, Ihr Auftrag oder Ihr Schritt ausgeführt wird, auch wenn der Build abgebrochen wird. Stellen Sie sicher, dass die von Ihnen geschriebenen Bedingungen den Status der übergeordneten Phase oder des Auftrags berücksichtigen.
Das folgende YAML-Beispiel zeigt die und failed()
die always()
Bedingungen. Der Schritt im ersten Auftrag wird auch ausgeführt, wenn Abhängigkeiten fehlschlagen oder der Build abgebrochen wird. Der zweite Auftrag wird nur ausgeführt, wenn der erste Auftrag fehlschlägt.
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
Sie können Variablen auch in Bedingungen festlegen und verwenden. Im folgenden Beispiel wird eine isMain
Variable festgelegt und verwendet, um sie als main
die 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)
Wichtig
Bedingungen werden ausgewertet, um zu bestimmen, ob eine Phase, ein Auftrag oder ein Schritt gestartet werden soll. Daher steht zur Laufzeit nichts zur Verfügung, das innerhalb dieser Arbeitseinheit berechnet wird. Wenn Sie beispielsweise über einen Auftrag verfügen, der eine Variable mithilfe eines Laufzeitausdrucks mit $[ ]
Syntax festlegt, können Sie diese Variable nicht in einer benutzerdefinierten Bedingung in diesem Auftrag verwenden.
Benutzerdefinierte Bedingungen
Wenn die integrierten Bedingungen Nicht Ihren Anforderungen entsprechen, können Sie benutzerdefinierte Bedingungen angeben. Sie schreiben Bedingungen als Ausdrücke in YAML-Pipelinedefinitionen.
Der Agent wertet den Ausdruck aus, der mit der innersten Funktion beginnt und nach außen verläuft. Das Endergebnis ist ein boolescher Wert, der bestimmt, ob die Aufgabe, der Auftrag oder die Phase ausgeführt werden soll. Eine vollständige Anleitung zur Syntax finden Sie unter "Ausdrücke".
Wenn eine Ihrer Bedingungen die Ausführung der Aufgabe auch nach dem Abbrechen des Builds ermöglicht, geben Sie einen angemessenen Wert für das Abbrechen des Timeouts an, damit diese Aufgaben genügend Zeit haben, um nach dem Abbrechen einer Ausführung durch den Benutzer abzuschließen.
Bedingungsergebnisse, wenn ein Build abgebrochen wird
Das Abbrechen eines Builds bedeutet nicht, dass alle Phasen, Aufträge oder Schritte nicht mehr ausgeführt werden. Welche Phasen, Aufträge oder Schritte nicht mehr ausgeführt werden, hängt von den von Ihnen angegebenen Bedingungen ab, und an welchem Punkt der Ausführung der Pipeline Sie den Build abgebrochen haben. Wenn das übergeordnete Element einer Phase, eines Auftrags oder eines Schritts übersprungen wird, wird die Aufgabe unabhängig von ihren Bedingungen nicht ausgeführt.
Eine Phase, ein Auftrag oder ein Schritt wird ausgeführt, wenn die Bedingungen ausgewertet werden true
. Wenn Ihre Bedingung den Status des übergeordneten Elements der Aufgabe nicht berücksichtigt, kann die Aufgabe auch dann ausgeführt werden, wenn das übergeordnete Element abgebrochen wird. Um zu steuern, ob Phasen, Aufträge oder Schritte mit Bedingungen ausgeführt werden, wenn ein Build abgebrochen wird, stellen Sie sicher, dass Sie eine Auftragsstatusüberprüfungsfunktion in Ihre Bedingungen einschließen.
Die folgenden Beispiele zeigen die Ergebnisse verschiedener Bedingungen, die auf Phasen, Aufträgen oder Schritten festgelegt sind, wenn der Build abgebrochen wird.
Phase (Beispiel 1)
In der folgenden Pipeline hängt standardmäßig stage2
von stage1
der Ausführung ab, ist condition
jedoch stage2
festgelegt, wann immer die Quellverzweigung ausgeführt wird main
, unabhängig vom stage1
Status.
Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und sie abbrechen, während stage1
sie ausgeführt wird, stage2
wird sie weiterhin ausgeführt, da eq(variables['Build.SourceBranch'], 'refs/heads/main')
sie ausgewertet wird 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
Phase (Beispiel 2)
In der folgenden Pipeline stage2
hängt standardmäßig davon stage1
ab. Auftrag B
in stage2
hat einen condition
Satz. Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und ihn während stage1
der Ausführung abbrechen, stage2
wird er nicht ausgeführt, obwohl er einen Auftrag enthält, dessen Bedingung ausgewertet wird true
.
Der Grund dafür ist, dass für stage2
der Standardwert condition: succeeded()
verwendet wird, der als beim Abbrechen von false
als stage1
ausgewertet wird. Daher wird stage2
übersprungen, und keiner der Aufträge wird ausgeführt.
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
Phase (Beispiel 3)
In der folgenden Pipeline hängt standardmäßig stage2
davon stage1
ab, und der Schritt innerhalb des Auftrags B
hat einen condition
Satz.
Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und während stage1
der Ausführung abbrechen, wird er nicht ausgeführt, stage2
obwohl er einen Schritt im Auftrag B
enthält, dessen Bedingung ausgewertet wird true
. Der Grund liegt darin, dass stage2
als Reaktion auf den Abbruch von stage1
übersprungen wird.
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')
Auftragsbeispiel 1
In der folgenden YAML-Pipeline hängt der Auftrag B
standardmäßig vom Auftrag A
ab, der Auftrag B
ist condition
jedoch so eingestellt, dass er immer ausgeführt wird, wenn die Quellverzweigung vorhanden ist main
. Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und ihn abbrechen, während der Auftrag A
ausgeführt wird, wird der Auftrag B
weiterhin ausgeführt, da eq(variables['Build.SourceBranch'], 'refs/heads/main')
er ausgewertet true
wird.
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
Wenn der Auftrag nur ausgeführt werden soll, wenn der Auftrag B
A
erfolgreich ist und die Buildquelle die main
Verzweigung ist, sollte dies condition
sein and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
.
Auftragsbeispiel 2
In der folgenden Pipeline hängt der Auftrag B
standardmäßig vom Auftrag A
ab. Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und ihn abbrechen, während der Auftrag A
ausgeführt wird, wird der Auftrag B
nicht ausgeführt, obwohl sein Schritt eine condition
Auswertung true
hat.
Der Grund dafür ist, dass für Auftrag B
der Standardwert condition: succeeded()
verwendet wird, der beim Abbrechen des Auftrags false
als A
ausgewertet wird. Daher wird der Auftrag B
übersprungen, und keiner der Schritte wird ausgeführt.
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())
Beispiel für Schritt
Sie können auch Bedingungen für Schritte festlegen.
In der folgenden Pipeline verfügt Schritt 2.3 über einen condition
Satz, der ausgeführt werden soll, wenn der Quellzweig ist main
. Wenn Sie einen Build auf der Verzweigung in die main
Warteschlange stellen und abbrechen, während die Schritte 2.1 oder 2.2 ausgeführt werden, wird Schritt 2.3 weiterhin ausgeführt, da eq(variables['Build.SourceBranch'], 'refs/heads/main')
die Werte true
ausgewertet werden.
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')
Bedingungseinstellungen
Die folgende Tabelle zeigt Beispieleinstellungen condition
, um verschiedene Ergebnisse zu erzielen.
Hinweis
Release.Artifacts.{artifact-alias}.SourceBranch
entspricht Build.SourceBranch
.
Gewünschtes Ergebnis | Beispielbedingungseinstellung |
---|---|
Führen Sie aus, wenn der Quellzweig haupt ist, auch wenn die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt fehlgeschlagen oder abgebrochen wurde. | eq(variables['Build.SourceBranch'], 'refs/heads/main') |
Führen Sie die Ausführung aus, wenn der Quellzweig haupt ist und die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt erfolgreich war. | and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) |
Führen Sie die Ausführung aus, wenn der Quellzweig nicht Hauptzweig ist und die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt erfolgreich war. | and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main')) |
Führen Sie für Benutzerthemazweige aus, wenn die übergeordnete oder vorherige Phase, der Auftrag oder der Schritt erfolgreich war. | and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/')) |
Führen Sie die Ausführung für CI-Builds (Continuous Integration) aus, wenn die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt erfolgreich war. | and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')) |
Führen Sie aus, wenn der Build durch eine Verzweigungsrichtlinie für eine Pullanforderung ausgelöst wurde, und die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt ist fehlgeschlagen. | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
Führen Sie die Ausführung für einen geplanten Build aus, auch wenn die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt fehlgeschlagen oder abgebrochen wurde. | eq(variables['Build.Reason'], 'Schedule') |
Führen Sie aus, wenn eine Variable auf "true" festgelegt ist, auch wenn die übergeordnete oder vorhergehende Phase, der Auftrag oder der Schritt fehlgeschlagen ist oder abgebrochen wurde. | eq(variables['System.debug'], true) |
Hinweis
Sie können festlegen, dass eine Bedingung ausgeführt wird, wenn eine Variable null ist (leere Zeichenfolge). Da alle Variablen in Azure Pipelines als Zeichenfolgen behandelt werden, entspricht null
eine leere Zeichenfolge der folgenden Pipeline:
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
Parameter in Bedingungen
Die Parametererweiterung erfolgt, bevor Bedingungen berücksichtigt werden. Wenn Sie daher einen Parameter in derselben Pipeline wie eine Bedingung deklarieren, können Sie den Parameter in die Bedingung einbetten. Das Skript in der folgenden YAML-Datei wird ausgeführt, weil parameters.doThing
es "true" ist.
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
Die condition
in der vorstehenden Pipeline enthaltene Kombination von zwei Funktionen: succeeded()
und eq('${{ parameters.doThing }}', true)
. Die Funktion succeeded()
überprüft, ob der vorherige Schritt erfolgreich war. Die succeeded()
Funktion gibt zurück true
, da kein vorheriger Schritt aufgetreten ist.
Die eq('${{ parameters.doThing }}', true)
Funktion überprüft, ob der doThing
Parameter gleich true
ist. Da der Standardwert lautet doThing
, wird true
die Bedingung standardmäßig zurückgegeben true
, es sei denn, die Pipeline legt einen anderen Wert fest.
Vorlagenparameter in Bedingungen
Wenn Sie einen Parameter an eine Vorlage übergeben, müssen Sie entweder den Wert des Parameters in Ihrer Vorlage festlegen oder templateContext verwenden, um den Parameter an die Vorlage zu übergeben.
Die folgende parameters.yml Datei deklariert z. B. den doThing
Parameter und standardwert:
# 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) }}
Der Pipelinecode verweist auf die parameters.yml Vorlage. Die Ausgabe der Pipeline liegt I did a thing
daran, dass der Parameter doThing
"true" ist.
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
Weitere Vorlagenparameterbeispiele finden Sie in der Vorlagenverwendungsreferenz.
In nachfolgenden Auftragsbedingungen verwendete Auftragsausgabevariablen
Sie können eine Variable für zukünftige Aufträge zur Verfügung stellen und sie in einer Bedingung angeben. Variablen, die für zukünftige Aufträge verfügbar sind, müssen wie im folgenden Code als Ausgabevariablen isOutput=true
mit mehreren Aufträgen gekennzeichnet werden:
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."
Variablen, die in einem Schritt erstellt wurden, der in nachfolgenden Schrittbedingungen verwendet wird
Sie können eine Variable erstellen, die für zukünftige Schritte zur Angabe in einer Bedingung verfügbar ist. Mithilfe von Schritten erstellte Variablen sind standardmäßig für zukünftige Schritte verfügbar und müssen nicht als Ausgabevariablen mit mehreren Stellen gekennzeichnet werden.
Es gibt einige wichtige Punkte, die Sie bei der Bereichsdefinition von Variablen beachten müssen, die anhand von Schritten erstellt werden.
- Variablen, die in einem Schritt in einem Auftrag erstellt wurden, sind auf die Schritte im selben Auftrag abgegrenzt.
- Variablen, die in einem Schritt erstellt wurden, sind in nachfolgenden Schritten nur als Umgebungsvariablen verfügbar.
- In einem Schritt erstellte Variablen können nicht in dem Schritt verwendet werden, der sie definiert.
Das folgende Beispiel zeigt das Erstellen einer Pipelinevariable in einem Schritt und die Verwendung der Variablen in der Bedingung und dem Skript eines nachfolgenden Schritts.
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'))
Häufig gestellte Fragen
Wie kann ich einen Auftrag auslösen, wenn ein vorheriger Auftrag mit Problemen erfolgreich war?
Sie können das Ergebnis des vorherigen Auftrags in einer Bedingung verwenden. Beispielsweise ermöglicht die Bedingung eq(dependencies.A.result,'SucceededWithIssues')
im folgenden YAML die Ausführung des Auftrags B
, da der Auftrag A
mit Problemen erfolgreich war.
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
Ich habe meinen Build abgebrochen, aber er wird weiterhin ausgeführt. Warum?
Dieses Problem kann auftreten, wenn eine in einer Phase konfigurierte Bedingung keine Auftragsstatusüberprüfungsfunktion enthält. Um das Problem zu beheben, fügen Sie der Bedingung eine Auftragsstatus-Überprüfungsfunktion hinzu.
Wenn Sie einen Auftrag abbrechen, während er sich in der Warteschleife befindet, aber nicht ausgeführt wird, wird der gesamte Auftrag abgebrochen, einschließlich aller anderen Phasen. Weitere Informationen finden Sie unter Bedingungsergebnisse, wenn ein Build weiter oben in diesem Artikel abgebrochen wird.