Angeben von Bedingungen

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

Sie können die Bedingungen festlegen, unter denen die einzelnen Stages, Aufträge oder Schritte ausgeführt werden. Standardmäßig werden Aufträge oder Stages ausgeführt, wenn sie nicht von einem anderen Auftrag oder einer anderen Stage abhängig sind, oder wenn alle Aufträge oder Stages, von denen sie abhängig sind, erfolgreich abgeschlossen wurden. Dies umfasst nicht nur direkte Abhängigkeiten, sondern auch deren Abhängigkeiten, die rekursiv berechnet werden. Schritte werden standardmäßig ausgeführt, wenn im zugehörigen Auftrag noch kein Fehler aufgetreten ist und der unmittelbar vorangehende Schritt abgeschlossen wurde. Sie können dieses Verhalten anpassen, indem Sie erzwingen, dass eine Stage, ein Auftrag oder ein Schritt auch bei einem Fehler einer vorherigen Abhängigkeit ausgeführt wird, oder indem Sie eine benutzerdefinierte Bedingung angeben.

Sie können Bedingungen angeben, unter denen ein Schritt, ein Auftrag oder eine Phase ausgeführt werden soll.

  • Nur, wenn die Überprüfung aller vorherigen direkten und indirekten Abhängigkeiten mit demselben Agentpool erfolgreich war. Wenn Sie über verschiedene Agentpools verfügen, werden diese Phasen oder Aufträge gleichzeitig ausgeführt. Dies ist die Standardeinstellung, wenn in der YAML-Datei keine Bedingung festgelegt ist.

  • Auch wenn eine vorherige Abhängigkeit fehlgeschlagen ist, außer wenn die Ausführung abgebrochen wurde. Verwenden Sie für diese Bedingung succeededOrFailed() in der YAML-Datei.

  • Auch wenn eine vorherige Abhängigkeit fehlgeschlagen ist, auch wenn die Ausführung abgebrochen wurde. Verwenden Sie für diese Bedingung always() in der YAML-Datei.

  • Nur wenn eine vorherige Abhängigkeit fehlgeschlagen ist. Verwenden Sie für diese Bedingung failed() in der YAML-Datei.

  • Benutzerdefinierte Bedingungen

Standardmäßig werden Schritte, Aufträge und Phasen ausgeführt, wenn alle direkten und indirekten Abhängigkeiten erfolgreich waren. Es ist so, als hätten Sie „condition: succeeded()“ angegeben (siehe erfolgreiche Statusfunktion).

jobs:
- job: Foo

  steps:
  - script: echo Hello!
    condition: always() # this step will always run, even if the pipeline is canceled

- job: Bar
  dependsOn: Foo
  condition: failed() # this job will only run if Foo fails

Sie können Variablen auch in Bedingungen verwenden.

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)

Die Bedingungen werden ausgewertet, um zu entscheiden, ob eine Stage, ein Auftrag oder ein Schritt gestartet werden soll. Demnach sind keine Berechnungen verfügbar, die während der Laufzeit in dieser Arbeitseinheit vorgenommen werden. Wenn Sie beispielsweise über einen Auftrag verfügen, der eine Variable mithilfe eines Laufzeitausdrucks mit einer $[ ]-Syntax festlegt, können Sie diese Variable nicht in Ihrer benutzerdefinierten Bedingung verwenden.

YAML wird in TFS nicht unterstützt.

Hinweis

Wenn Sie Ihre eigene condition-Eigenschaft für eine Stage/einen Auftrag/Schritt angeben, überschreiben Sie die zugehörige Standardeinstellung condition: succeeded(). Dies kann dazu führen, dass Ihre Stage/Ihr Auftrag/Ihr Schritt auch dann ausgeführt wird, wenn der Build abgebrochen wird. Stellen Sie beim Schreiben eigener Bedingungen sicher, dass Sie den Status der übergeordneten Stage/des übergeordneten Auftrags berücksichtigen.

Benutzerdefinierte Bedingung aktivieren

Sollten die integrierten Bedingungen Ihre Anforderungen nicht erfüllen, können Sie benutzerdefinierte Bedingungen definieren.

Bedingungen werden als Ausdrücke in YAML-Pipelines geschrieben. Der Agent wertet den Ausdruck aus. Dabei beginnt er mit der innersten Funktion und arbeitet sich nach außen. Das endgültige Ergebnis ist ein boolescher Wert, der bestimmt, ob der Vorgang, der Auftrag oder die Phase ausgeführt werden soll. Eine vollständige Anleitung zur Syntax finden Sie im Artikel Ausdrücke.

Ermöglicht eine Ihrer Bedingungen die Ausführung der Aufgabe auch dann, wenn der Buildvorgang von einem Benutzer abgebrochen wurde? Falls ja, geben Sie einen angemessenen Wert für die Einstellung Zeitüberschreitung abbrechen an, sodass genügend Zeit zum Abschließen derartiger Aufgaben zur Verfügung steht, nachdem der Benutzer eine Ausführung abgebrochen hat.

Pipelineverhalten beim Abbrechen des Buildvorgangs

Wenn ein Build abgebrochen wird, bedeutet dies nicht, dass alle Stages, Aufträge oder Schritte nicht mehr ausgeführt werden. Die Entscheidung hängt von der von Ihnen angegebenen Stage, dem Auftrag oder dem angegebenen Schritt conditions und von dem Punkt der Pipelineausführung ab, an dem Sie den Build abgebrochen haben.

Wenn Ihre Bedingung den Zustand des übergeordneten Elements Ihrer Stage/Ihres Auftrags/Schritts nicht berücksichtigt und die Bedingung als true ausgewertet wird, wird die Stage, der Auftrag oder der Schritt ausgeführt, selbst wenn das übergeordnete Element abgebrochen wird. Sollte das übergeordnete Element übersprungen werden, wird Ihre Stage, Ihr Auftrag oder Ihr Schritt nicht ausgeführt.

Wir sehen uns nun einige Beispiele an.

In dieser Pipeline ist stage2 standardmäßig von stage1 und stage2 abhängig und condition ist festgelegt. stage2 wird nur ausgeführt, wenn die Quellverzweigung mainist.

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

Wenn Sie einen Build für die main-Verzweigung in die Warteschlange stellen und ihn während der Ausführung von stage1 abbrechen, wird stage2 weiterhin ausgeführt, da eq(variables['Build.SourceBranch'], 'refs/heads/main') als true ausgewertet wird.

In dieser Pipeline ist stage2 von stage1 abhängig. Für Auftrag B ist condition festgelegt.

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

Wenn Sie einen Build für die main-Verzweigung in die Warteschlange stellen und ihn während der Ausführung von stage1 abbrechen, stage2wird nicht ausgeführt, obwohl darin ein Auftrag B enthalten ist, dessen Bedingung als true ausgewertet wird. 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.

Angenommen, Sie verfügen über die folgende YAML-Pipeline. Beachten Sie, dass standardmäßig stage2 von stage1 abhängig ist und dass für script: echo 2 eine condition-Einstellung festgelegt ist.

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

Wenn Sie einen Build für die main-Verzweigung in die Warteschlange stellen und ihn während der Ausführung von stage1 abbrechen, stage2wird nicht ausgeführt, obwohl darin ein Schritt im Auftrag B enthalten ist, dessen Bedingung als true ausgewertet wird. Der Grund liegt darin, dass stage2 als Reaktion auf den Abbruch von stage1 übersprungen wird.

Um zu verhindern, dass Stages, Aufträge oder Schritte mit conditions ausgeführt werden, wenn ein Build abgebrochen wird, stellen Sie beim Schreiben von conditions sicher, dass Sie den Status der übergeordneten Elemente berücksichtigen. Weitere Informationen finden Sie unter Auftragsstatusfunktionen.

Beispiele

Für die Hauptverzweigung ausführen, auch bei Abbruch, auch bei Fehlern

eq(variables['Build.SourceBranch'], 'refs/heads/main')

Für die Hauptverzweigung ausführen, bei Erfolg

and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Ausführen, wenn die Verzweigung keine Hauptverzweigung ist, bei Erfolg

and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))

Für Benutzerthemenverzweigungen ausführen, bei Erfolg

and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))

Für CI-Builds ausführen, bei Erfolg

and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))

Ausführen, wenn der Build von einer Verzweigungsrichtlinie für eine Pull-Anforderung ausgeführt wird, bei Fehlern

and(failed(), eq(variables['Build.Reason'], 'PullRequest'))

Ausführen, wenn der Build geplant ist, auch bei Fehlern, auch bei Abbruch

eq(variables['Build.Reason'], 'Schedule')

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

Immer ausführen, wenn eine Variable auf „true“ festgelegt ist, auch bei Abbruch, auch bei Fehlern

eq(variables['System.debug'], true)

Ausführen, wenn eine Variable Null ist (leere Zeichenfolge)

Da alle Variablen in Azure Pipelines als Zeichenfolgen behandelt werden, entspricht eine leere Zeichenfolge in dieser Pipeline null.

variables:
- name: testEmpty
  value: ''

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

Verwenden eines Vorlagenparameters als Teil einer Bedingung

Wenn Sie einen Parameter in der gleichen Pipeline deklarieren, in der sich auch eine Bedingung befindet, erfolgt die Parametererweiterung vor der Berücksichtigung von Bedingungen. In diesem Fall können Sie Parameter in Bedingungen einbetten. Das Skript in dieser YAML-Datei wird ausgeführt, da parameters.doThing „true“ ist.

condition der Pipeline kombiniert zwei Funktionen: succeeded() und eq('${{ parameters.doThing }}', true). Die Funktion succeeded() überprüft, ob der vorherige Schritt erfolgreich war. Die Funktion succeeded() gibt „true“ zurück, da es keinen vorherigen Schritt gab.

Die Funktion eq('${{ parameters.doThing }}', true) überprüft, ob der doThing-Parameter gleich true ist. Da der Standardwert für doThing „true“ ist, gibt die Bedingung standardmäßig „true“ zurück, es sei denn, es wird ein anderer Wert in der Pipeline festgelegt.

Weitere Vorlagenparameterbeispiele finden Sie unter Vorlagentypen und Verwendung.

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

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

Wenn Sie einen Parameter an eine Vorlage übergeben, müssen Sie den Wert des Parameters in Ihrer Vorlage festlegen oder templateContext verwenden, um Eigenschaften an Vorlagen zu übergeben.

# 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) }}
# azure-pipeline.yml
parameters:
- name: doThing
  default: true 
  type: boolean

trigger:
- none

extends:
  template: parameters.yml

Die Ausgabe dieser Pipeline ist I did a thing, weil der Parameter doThing „true“ ist.

Verwenden der Ausgabevariablen eines Auftrags in einer Bedingung in einem nachfolgenden Auftrag

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 mit als Ausgabevariablen für mehrere Aufträge isOutput=true 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."

Verwenden der in einem Schritt erstellten Pipelinevariablen in einer Bedingung in einem nachfolgenden Schritt

Sie können eine Variable für zukünftige Schritte zur Verfügung stellen und sie in einer Bedingung angeben. Standardmäßig sind aus einem Schritt erstellte Variablen für zukünftige Schritte verfügbar und müssen nicht mit als Ausgabevariablen für mehrere AufträgeisOutput=true gekennzeichnet werden.

Es gibt einige wichtige Punkte, die in Bezug auf den oben genannten Ansatz und die Bereichsdefinition zu beachten sind:

  • In einem Schritt eines Auftrags erstellte Variablen werden auf die Schritte im gleichen Auftrag festgelegt.
  • In einem Schritt erstellte Variablen sind nur in nachfolgenden Schritten als Umgebungsvariablen verfügbar.
  • In einem Schritt erstellte Variablen können nicht in dem Schritt verwendet werden, der sie definiert.

Im Folgenden finden Sie ein Beispiel für 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 will be available to subsquent steps.
- bash: |
    echo "##vso[task.setvariable variable=doThing]Yes"
  displayName: Step 1

# This step is able to use doThing, so it uses it in its condition
- script: |
    # You can 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 verwenden. In dieser YAML-Datei ermöglicht die Bedingung eq(dependencies.A.result,'SucceededWithIssues') z. B. die Ausführung des Auftrags, da Auftrag A mit Problemen erfolgreich abgeschlossen wurde.

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. Woran liegt das?

Dieses Problem tritt auf, wenn die in der Stage 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 zwar in der Warteschlange befindet, aber nicht ausgeführt wird, wird der gesamte Auftrag abgebrochen, einschließlich aller anderen Stages.

Erfahren Sie mehr über das Verhalten einer Pipeline beim Abbrechen eines Builds.