Określanie warunków

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

Możesz określić warunki uruchamiania każdego etapu, zadania lub kroku. Domyślnie zadanie lub etap jest uruchamiane, jeśli nie zależy od innego zadania lub etapu, lub jeśli wszystkie zadania lub etapy, od których zależy, zostały ukończone i zakończyły się pomyślnie. Obejmuje to nie tylko bezpośrednie zależności, ale także ich zależności obliczane rekursywnie. Domyślnie krok jest uruchamiany, jeśli dotychczas wszystko w zadaniu powiodło się, a krok poprzedni został wykonany. To zachowanie można dostosować, wymuszając uruchomienie etapu, zadania lub kroku, nawet jeśli poprzednia zależność zakończy się niepowodzeniem lub przez określenie warunku niestandardowego.

Możesz określić warunki, od których będzie zależało uruchomienie kroku, zadania lub etapu.

  • Tylko wtedy, gdy wszystkie poprzednie zależności bezpośrednie i pośrednie z tą samą pulą agentów zakończyły się pomyślnie. Jeśli masz różne pule agentów, te etapy lub zadania będą uruchamiane współbieżnie. Jest to ustawienie domyślne, jeśli nie ma warunku ustawionego w yaML.

  • Nawet jeśli poprzednia zależność nie powiodła się, chyba że przebieg został anulowany. Użyj succeededOrFailed() w pliku YAML dla tego warunku.

  • Nawet jeśli poprzednia zależność nie powiodła się, nawet jeśli przebieg został anulowany. Użyj always() w pliku YAML dla tego warunku.

  • Tylko wtedy, gdy poprzednia zależność nie powiodła się. Użyj failed() w pliku YAML dla tego warunku.

  • Warunki niestandardowe

Domyślnie kroki, zadania i etapy są uruchamiane, jeśli wszystkie zależności bezpośrednie i pośrednie zakończyły się pomyślnie. Jest tak, jakby określono "warunek: succeeded()" (zobacz funkcję stanu powodzenia).

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

Zmienne można również używać w warunkach.

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)

Warunki są oceniane, aby zdecydować, czy rozpocząć etap, zadanie, czy krok. Oznacza to, że żadne zasoby obliczeniowe w czasie wykonywania w ramach tej jednostki pracy nie będą dostępne. Jeśli na przykład masz zadanie, które ustawia zmienną przy użyciu wyrażenia środowiska uruchomieniowego przy użyciu $[ ] składni, nie można użyć tej zmiennej w warunku niestandardowym.

Język YAML nie jest obsługiwany w programie TFS.

Uwaga

Po określeniu własnej condition właściwości dla etapu /zadania / kroku zastąpisz jego wartość domyślną condition: succeeded(). Może to prowadzić do uruchomienia etapu/zadania/kroku, nawet jeśli kompilacja została anulowana. Upewnij się, że podczas pisania własnych warunków uwzględnisz stan etapu nadrzędnego/zadania.

Włączanie warunku niestandardowego

Jeśli wbudowane warunki nie spełniają Twoich potrzeb, możesz określić warunki niestandardowe.

Warunki są zapisywane jako wyrażenia w potokach YAML. Agent ocenia wyrażenie, rozpoczynając od najbardziej wewnętrznej funkcji, a następnie przechodzi na zewnątrz. Wynik końcowy to wartość logiczna określająca, czy zadanie, krok lub etap powinno być uruchomione, czy nie. Zapoznaj się z artykułem dotyczącym wyrażeń , aby uzyskać pełny przewodnik po składni.

Czy którykolwiek z warunków umożliwia uruchomienie zadania nawet po anulowaniu kompilacji przez użytkownika? Jeśli tak, określ rozsądną wartość limitu czasu anulowania, aby tego rodzaju zadania miały wystarczająco dużo czasu na ukończenie po anulowaniu przebiegu przez użytkownika.

Zachowanie potoku po anulowaniu kompilacji

Po anulowaniu kompilacji nie oznacza to, że wszystkie etapy, zadania lub kroki przestaną działać. Decyzja zależy od określonego etapu, zadania lub kroku conditions i w jakim momencie wykonania potoku anulowano kompilację.

Jeśli warunek nie uwzględnia stanu nadrzędnego etapu/zadania/kroku, to jeśli warunek zostanie obliczony na truewartość , etap, zadanie lub krok zostanie uruchomiony, nawet jeśli jego element nadrzędny zostanie anulowany. Jeśli jego element nadrzędny zostanie pominięty, etap, zadanie lub krok nie zostanie uruchomiony.

Przyjrzyjmy się kilku przykładom.

W tym potoku domyślnie stage2 zależy od stage1 zestawu i stage2 ma condition zestaw. stage2 działa tylko wtedy, gdy gałąź źródłowa to main.

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

Jeśli kolejkujesz kompilację w main gałęzi i anulujesz ją podczas stage1 uruchamiania, nadal będzie działać, stage2 ponieważ eq(variables['Build.SourceBranch'], 'refs/heads/main') daje wartość .true

W tym potoku stage2 zależy od stage1elementu . Zadanie B ma condition zestaw.

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

Jeśli kolejkujesz kompilację w main gałęzi i anulujesz ją podczas stage1 działania, nie zostanie uruchomiona,stage2 mimo że zawiera zadanieB, którego warunek daje wartość true. Przyczyną jest to, że stage2 ma wartość domyślną condition: succeeded(), która daje wartość w przypadku falsestage1 anulowania. stage2 W związku z tym nie jest pomijany, a żadne z jego zadań nie jest uruchamiane.

Załóżmy, że masz następujący potok YAML. Zwróć uwagę, że domyślnie stage2 zależy od stage1 elementu i ma script: echo 2condition ustawiony dla niego zestaw.

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

Jeśli kolejkujesz kompilację w main gałęzi i anulujesz ją podczas stage1 działania, nie zostanie uruchomiona,stage2 mimo że zawiera krok w zadaniuB, którego warunek daje wartość true. Przyczyną jest stage2 pominięcie w odpowiedzi na stage1 anulowanie.

Aby zapobiec uruchamianiu etapów, zadań lub kroków po conditions anulowaniu kompilacji, upewnij się, że podczas zapisywania elementu nadrzędnego należy wziąć pod uwagę stan elementu nadrzędnego conditions. Aby uzyskać więcej informacji, zobacz Funkcje stanu zadania.

Przykłady

Uruchom polecenie dla gałęzi głównej, nawet jeśli zostało anulowane, nawet jeśli kończy się niepowodzeniem

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

Uruchom polecenie dla gałęzi głównej, jeśli zakończy się powodzeniem

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

Uruchom polecenie , jeśli gałąź nie jest główna, jeśli zakończy się powodzeniem

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

Uruchom polecenie dla gałęzi tematu użytkownika, jeśli zakończy się powodzeniem

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

Uruchamianie dla kompilacji ciągłej integracji (CI) w przypadku powodzenia

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

Uruchom polecenie , jeśli kompilacja jest uruchamiana przez zasady gałęzi dla żądania ściągnięcia, jeśli niepowodzenie

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

Uruchom polecenie , jeśli kompilacja jest zaplanowana, nawet jeśli kończy się niepowodzeniem, nawet jeśli została anulowana

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

Release.Artifacts. {artifact-alias}. Element SourceBranch jest odpowiednikiem elementu Build.SourceBranch.

Zawsze uruchamiaj, jeśli zmienna jest ustawiona na wartość true, nawet jeśli została anulowana, nawet w przypadku niepowodzenia

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

Uruchom polecenie , jeśli zmienna ma wartość null (pusty ciąg)

Ponieważ wszystkie zmienne są traktowane jako ciągi w usłudze Azure Pipelines, pusty ciąg jest odpowiednikiem null tego potoku.

variables:
- name: testEmpty
  value: ''

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

Używanie parametru szablonu w ramach warunku

Podczas deklarowania parametru w tym samym potoku, który zawiera warunek, rozszerzenie parametru ma miejsce przed rozważeniem warunków. W takim przypadku parametry można osadzić wewnątrz warunków. Skrypt w tym pliku YAML zostanie uruchomiony, ponieważ parameters.doThing ma wartość true.

Element condition w potoku łączy dwie funkcje: succeeded() i eq('${{ parameters.doThing }}', true). Funkcja succeeded() sprawdza, czy poprzedni krok zakończył się pomyślnie. Funkcja succeeded() zwraca wartość true, ponieważ nie było poprzedniego kroku.

Funkcja eq('${{ parameters.doThing }}', true) sprawdza, czy parametr doThing jest równy true. Ponieważ wartość domyślna funkcji doThing ma wartość true, warunek zostanie zwrócony domyślnie, chyba że w potoku zostanie ustawiona inna wartość.

Aby uzyskać więcej przykładów parametrów szablonu, zobacz Typy szablonów i użycie.

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

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

Po przekazaniu parametru do szablonu należy ustawić wartość parametru w szablonie lub użyć szablonuContext, aby przekazać właściwości do szablonów.

# 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

Dane wyjściowe tego potoku są I did a thing spowodowane tym, że parametr doThing ma wartość true.

Używanie zmiennej wyjściowej z zadania w warunku kolejnego zadania

Możesz udostępnić zmienną przyszłym zadaniu i określić ją w warunku. Zmienne dostępne dla przyszłych zadań muszą być oznaczone jako zmienne wyjściowe z wieloma zadaniami przy użyciu polecenia isOutput=true.

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

Używanie zmiennej potoku utworzonej na podstawie kroku w warunku kolejnego kroku

Możesz udostępnić zmienną w przyszłych krokach i określić ją w warunku. Domyślnie zmienne utworzone na podstawie kroku są dostępne dla przyszłych kroków i nie muszą być oznaczone jako zmienne wyjściowe z wieloma zadaniami przy użyciu polecenia isOutput=true.

Należy pamiętać o kilku ważnych kwestiach dotyczących powyższego podejścia i określania zakresu:

  • Zmienne utworzone w kroku zadania będą ograniczone do kroków w tym samym zadaniu.
  • Zmienne utworzone w kroku będą dostępne tylko w kolejnych krokach jako zmienne środowiskowe.
  • Zmiennych utworzonych w kroku nie można używać w kroku, który je definiuje.

Poniżej przedstawiono przykład tworzenia zmiennej potoku w kroku i używania zmiennej w kolejnym kroku warunku i skryptu.

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

Często zadawane pytania

Jak mogę wyzwolić zadanie, jeśli poprzednie zadanie zakończyło się z błędami?

Możesz użyć wyniku poprzedniego zadania. Na przykład w tym pliku YAML warunek eq(dependencies.A.result,'SucceededWithIssues') umożliwia uruchomienie zadania, ponieważ zadanie A zakończyło się pomyślnie.

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

Anulowano moją kompilację, ale nadal działa. Co się dzieje?

Ten problem występuje, jeśli warunek skonfigurowany na etapie nie zawiera funkcji sprawdzania stanu zadania. Aby rozwiązać ten problem, dodaj funkcję sprawdzania stanu zadania do warunku. Jeśli anulujesz zadanie w kolejce, ale nie zostanie uruchomione, całe zadanie zostanie anulowane, w tym wszystkie pozostałe etapy.

Dowiedz się więcej o zachowaniu potoku po anulowaniu kompilacji.