Freigeben über


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 stage1der 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 stage1ab, 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 truewird.

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 BA 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 truehat.

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

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 trueausgewertet 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: ${{ 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 trueist. Da der Standardwert lautet doThing , wird truedie 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 AusgabevariablenisOutput=truemit 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.