Udostępnij przez


Wyrażenia

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

Ważne

Wybierz wersję z selektora wersji zawartości usługi Azure DevOps.

Wybierz wersję tego artykułu odpowiadającą twojej platformie i wersji. Selektor wersji znajduje się powyżej spisu treści. Wyszukaj platformę i wersję usługi Azure DevOps.

Użyj wyrażeń do określenia ciągu, wartości logicznej lub liczbowej podczas projektowania potoku. Gdy wyrażenie zwraca tablicę, stosowane są reguły indeksowania normalnego, a indeks zaczyna się od 0.

Najczęstszym zastosowaniem wyrażeń jest w warunkach do określania, czy zadanie lub krok powinny być uruchomione.

# Expressions are used to define conditions for a step, job, or stage
steps:
- task: ...
  condition: <expression>

Innym typowym zastosowaniem wyrażeń jest definiowanie zmiennych. Wyrażenia można oceniać w czasie kompilacji lub w czasie wykonywania. Używaj wyrażeń czasu kompilacji w dowolnym miejscu; użyj wyrażeń środowiska uruchomieniowego w zmiennych i warunkach. Użyj wyrażeń środowiska uruchomieniowego, aby obliczyć zawartość zmiennych i stanu (na przykład: condition).

# Two examples of expressions used to define variables
# The first one, a, is evaluated when the YAML file is compiled into a plan.
# The second one, b, is evaluated at runtime.
# Note the syntax ${{}} for compile time and $[] for runtime expressions.
variables:
  a: ${{ <expression> }}
  b: $[ <expression> ]

Różnica między składniami wyrażeń czasu wykonywania i kompilacji jest przede wszystkim tym, jaki kontekst jest dostępny. W wyrażeniu czasu kompilacji (${{ <expression> }}) masz dostęp do parameters i statycznie zdefiniowanych variables. W wyrażeniu środowiska uruchomieniowego ($[ <expression> ]) masz dostęp do większej liczby variables, ale nie parametrów.

W tym przykładzie wyrażenie środowiska uruchomieniowego ustawia wartość $(isMain). Zmienna statyczna w wyrażeniu kompilacji ustawia wartość $(compileVar).

variables:
  staticVar: 'my value' # static variable
  compileVar: ${{ variables.staticVar }} # compile time expression
  isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression

steps:
  - script: |
      echo ${{variables.staticVar}} # outputs my value
      echo $(compileVar) # outputs my value
      echo $(isMain) # outputs True

Wyrażenie może być literałem, odwołaniem do zmiennej, odwołaniem do zależności, funkcji lub prawidłowej zagnieżdżonej kombinacji tych typów.

Literały

W ramach wyrażenia można użyć literałów boolowskich, null, liczbowych, ciągów lub wersji.

# Examples
variables:
  someBoolean: ${{ true }} # case insensitive, so True or TRUE also works
  someNumber: ${{ -1.2 }}
  someString: ${{ 'a b c' }}
  someVersion: ${{ 1.2.3 }}

logiczny

True i False są wyrażeniami logicznymi.

Null (zero)

Null to specjalne wyrażenie literału, które jest zwracane, gdy nie znaleziono odpowiednika w słowniku, na przykład (variables['noSuch']). Wartość null może być wynikiem wyrażenia, ale nie może być wywoływana bezpośrednio w wyrażeniu.

Liczba

Zaczyna się od "-", "." lub "0" do "9".

Sznurek

Musi być cytowany pojedynczo. Na przykład: 'this is a string'.

Aby wyrazić literał pojedynczego cudzysłowu, należy go ująć za pomocą pojedynczego cudzysłowu. Na przykład: 'It''s OK if they''re using contractions.'.

Możesz użyć znaku pionowej kreski (|) dla ciągów wielowierszowych.

myKey: |
  one
  two
  three

Wersja

Numer wersji składający się z maksymalnie czterech segmentów. Musi zaczynać się od liczby oraz zawierać dwie lub trzy kropki (.). Na przykład: 1.2.3.4.

Zmienne

W ramach wyrażenia można uzyskać dostęp do zmiennych przy użyciu jednej z dwóch składni:

  • Składnia indeksu: variables['MyVar']
  • Składnia dereferencji właściwości: variables.MyVar

Aby użyć składni odwołania do właściwości, nazwa właściwości musi:

  • a-Z Rozpocznij od lub_
  • Następuje po a-Z, 0-9 lub _

Różne zmienne są dostępne w zależności od kontekstu wykonywania.

  • Jeśli tworzysz potoki przy użyciu języka YAML, zmienne potoku są dostępne.
  • Jeśli tworzysz potoki kompilacji przy użyciu edytora klasycznego, zmienne kompilacji są dostępne.
  • Jeśli tworzysz potoki wydania przy użyciu edytora klasycznego, zmienne wydania są dostępne.

Zmienne są zawsze ciągami. Jeśli chcesz użyć wpisanych wartości, użyj parametrów.

Uwaga

Istnieje ograniczenie dotyczące używania zmiennych z wyrażeniami zarówno dla potoków klasycznych, jak i YAML podczas konfigurowania takich zmiennych za pośrednictwem interfejsu użytkownika karty zmiennych. Zmienne zdefiniowane jako wyrażenia nie powinny zależeć od innej zmiennej z wyrażeniem w wartości, ponieważ nie ma gwarancji , że oba wyrażenia będą prawidłowo oceniane. Na przykład mamy zmienną a , której wartość $[ <expression> ] jest używana jako część wartości zmiennej b. Ponieważ kolejność zmiennych przetwarzania nie jest gwarantowana, zmienna może mieć niepoprawną wartość zmiennej ba po ocenie.

Te konstrukcje można używać tylko podczas konfigurowania zmiennych za pomocą słowa kluczowego zmiennych w potoku YAML. Należy umieścić zmienne w kolejności, w której powinny być przetwarzane, aby uzyskać poprawne wartości po przetworzeniu.

Functions

Możesz użyć następujących wbudowanych funkcji w wyrażeniach.

oraz

  • Oblicza wartość True, jeśli wszystkie parametry są True.
  • Parametry minimalne: 2. Maksymalna liczba parametrów: N.
  • Rzutuje parametry na wartość logiczną na potrzeby oceny.
  • Zwarcie po pierwszym False.
  • Przykład: and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))

połączyć

  • Oblicza parametry w kolejności (od lewej do prawej) i zwraca pierwszą wartość, która nie ma wartości null ani pustego ciągu.
  • Zwraca wartość bez wartości, jeśli wszystkie wartości parametrów mają wartość null lub puste ciągi.
  • Parametry minimalne: 2. Maksymalna liczba parametrów: N.
  • Przykład: coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')

zawiera

  • Oblicza, czy lewy True ciąg parametru zawiera odpowiedni parametr.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Rzutuje parametry na ciąg znaków w celu oceny.
  • Wykonuje porządkowe porównanie przypadków ignorowania.
  • Przykład: contains('ABCDE', 'BCD') (zwraca wartość True).

zawieraWartość

  • True Ocenia, czy lewy parametr jest tablicą, a jakikolwiek element tej tablicy jest równy prawemu parametrowi. True Ocenia również, czy lewy parametr jest obiektem, a wartość dowolnej właściwości jest równa prawego parametru.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Jeśli lewy parametr jest tablicą, przekonwertuj każdy element, aby był zgodny z typem odpowiedniego parametru. Jeśli lewy parametr jest obiektem, przekonwertuj wartość każdej właściwości, aby dopasować typ odpowiedniego parametru. Porównanie równości dla każdego określonego elementu ocenia False , jeśli konwersja się nie powiedzie.
  • Porównanie porządkowe z ignorowaniem wielkości liter dla ciągów znaków.
  • Zwarcie następuje po pierwszym dopasowaniu

Uwaga

W przepływie YAML nie ma dosłownej składni do określania tablicy. Ta funkcja ma ograniczone zastosowanie w potokach ogólnych. Jest przeznaczony do użycia w kontekście dekoratora potoku z tablicami dostarczanymi przez system, takimi jak lista kroków.

Możesz użyć containsValue wyrażenia , aby znaleźć zgodną wartość w obiekcie. Oto przykład przedstawiający wyszukiwanie na liście gałęzi źródłowych, aby znaleźć dopasowanie dla Build.SourceBranch.

parameters:
- name: branchOptions
  displayName: Source branch options
  type: object
  default:
    - refs/heads/main
    - refs/heads/test

jobs:
  - job: A1 
    steps:
    - ${{ each value in parameters.branchOptions }}:
      - script: echo ${{ value }}

  - job: B1 
    condition: ${{ containsValue(parameters.branchOptions, variables['Build.SourceBranch']) }}
    steps:
      - script: echo "Matching branch found"

convertToJson

  • Weź obiekt złożony i przekształć go na format JSON.
  • Minimalne parametry: 1. Maksymalna liczba parametrów: 1.
parameters:
  - name: listOfValues
    type: object
    default:
      this_is:
        a_complex: object
        with:
          - one
          - two

steps:
- script: |
    echo "${MY_JSON}"
  env:
    MY_JSON: ${{ convertToJson(parameters.listOfValues) }}

Dane wyjściowe skryptu:

{
  "this_is": {
    "a_complex": "object",
    "with": [
      "one",
      "two"
    ]
  }
}

licznik

  • Tej funkcji należy używać tylko w wyrażeniu, które definiuje zmienną. Nie używaj go jako części warunku dla kroku, zadania lub etapu.
  • Oblicza liczbę, która zwiększa się przy każdym uruchomieniu potoku.
  • Przyjmuje dwa parametry: prefix i seed.
  • prefix jest wyrażeniem ciągu. Funkcja śledzi oddzielną wartość licznika dla każdego niepowtarzalnego elementu prefix. Użyj znaków UTF-16 w pliku prefix.
  • seed to wartość początkowa licznika.

Możesz utworzyć licznik, który będzie automatycznie zwiększał się o jeden za każdym razem, gdy uruchomisz potok. Podczas definiowania licznika podaj prefix i seed. W poniższym przykładzie przedstawiono tę koncepcję.

variables:
  major: 1
  # define minor as a counter with the prefix as variable major, and seed as 100.
  minor: $[counter(variables['major'], 100)]

steps:
- bash: echo $(minor)

Wartość minor w poprzednim przykładzie to 100 podczas pierwszego uruchomienia potoku. W drugim przebiegu wartość to 101, o ile wartość major pozostaje 1.

Jeśli edytujesz plik YAML i zaktualizujesz wartość zmiennej major na 2, wartość minor wynosi 100 przy następnym uruchomieniu potoku. Kolejne uruchomienia zwiększają licznik do 101, 102, 103 itd.

Jeśli później edytujesz plik YAML i ustawisz wartość major z powrotem na 1, wartości licznika zostaną wznowione od miejsca, w którym została przerwana dla tego prefiksu. W tym przykładzie zostanie wznowione o godzinie 102.

W poniższym przykładzie pokazano, jak ustawić zmienną, która będzie działać jako licznik rozpoczynający się od 100, zwiększający się o 1 przy każdym uruchomieniu i resetujący się do 100 każdego dnia.

Uwaga

pipeline.startTime jest niedostępna poza wyrażeniami. pipeline.startTime formatuje system.pipelineStartTime do obiektu daty i godziny, aby wyrażenia mogły go używać. Domyślna strefa czasowa pipeline.startTime to UTC. Możesz zmienić strefę czasową organizacji.

jobs:
- job:
  variables:
    a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
  steps:
  - bash: echo $(a)

W poniższym przykładzie przedstawiono licznik, który utrzymuje odrębną wartość dla pull requestów i procesów CI.

variables:
  patch: $[counter(variables['build.reason'], 0)]

Liczniki są ograniczone zakresowo do potoku. Innymi słowy, rurociąg zwiększa wartość licznika dla każdego przebiegu. Żadne liczniki nie są objęte zakresem projektu.

kończy się znakiem/ciągiem

  • Ocenia, czy True ciąg znaków lewy kończy się na ciąg znaków prawy.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Rzutuje parametry na ciąg znaków w celu oceny.
  • Wykonuje porządkowe porównanie przypadków ignorowania.
  • Przykład: endsWith('ABCDE', 'DE') (zwraca wartość True)

Eq

  • True Ocenia, czy parametry są równe
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Zwraca wartość False w przypadku niepowodzenia konwersji.
  • Porządkowe porównanie przypadków dla ciągów.
  • Przykład: eq(variables.letters, 'ABC')

układ

  • Oblicza końcowe parametry i wstawia je do ciągu wiodącego parametru
  • Minimalne parametry: 1. Maksymalna liczba parametrów: N
  • Przykład: format('Hello {0} {1}', 'John', 'Doe')
  • Używa niestandardowych specyfikatorów formatu daty i czasu platformy .NET do formatowania daty (, yyyy, yy, MM, M, dd, d, HH, H, m, mm, ss, s, f, ff, ffff)
  • Przykład: format('{0:yyyyMMdd}', pipeline.startTime). W tym przypadku pipeline.startTime jest to specjalna zmienna obiektu daty i godziny.
  • Ucieczka przez podwojenie nawiasów klamrowych. Na przykład: format('literal left brace {{ and literal right brace }}').

Ge

  • Ocenia, czy lewy True parametr jest większy niż lub równy właściwemu parametrowi
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Błędy w przypadku niepowodzenia konwersji.
  • Porównanie ciągów bez uwzględniania wielkości liter.
  • Przykład: ge(5, 5) (zwraca wartość True)

Gt

  • Ocenia, czy lewy True parametr jest większy niż właściwy parametr
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Błędy w przypadku niepowodzenia konwersji.
  • Porządkowe porównanie przypadków dla ciągów.
  • Przykład: gt(5, 2) (zwraca wartość True)

w

  • Ocenia, czy lewy True parametr jest równy dowolnemu właściwemu parametrowi
  • Minimalne parametry: 1. Maksymalna liczba parametrów: N
  • Konwertuje prawe parametry na zgodny typ lewego parametru. Ocena równości sprawdza False w przypadku niepowodzenia konwersji.
  • Porównanie ciągów znakowych bez uwzględniania wielkości liter przy użyciu mechanizmu porządkowego.
  • Krótkie spięcia po pierwszym dopasowaniu
  • Przykład: in('B', 'A', 'B', 'C') (zwraca wartość True)

Plik IIIF

  • Zwraca drugi parametr, jeśli pierwszy parametr zwróci wartość True, a trzeci parametr w przeciwnym razie
  • Minimalne parametry: 1. Maksymalna liczba parametrów: 3
  • Pierwszy parametr musi być warunkiem
  • Przykład: iif(eq(variables['Build.Reason'], 'PullRequest'), 'ManagedDevOpsPool', 'Azure Pipelines') zwraca wartość "ManagedDevOpsPool", gdy potok jest uruchamiany w odpowiedzi na pull request (żądanie ściągnięcia).

dołączyć

  • Łączy wszystkie elementy w prawej tablicy parametrów oddzielone ciągiem parametrów po lewej stronie.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Każdy element w tablicy jest konwertowany na ciąg. Obiekty złożone są konwertowane na pusty ciąg.
  • Jeśli właściwy parametr nie jest tablicą, wynik jest prawidłowym parametrem przekonwertowanym na ciąg.

W tym przykładzie dodajemy średnik między poszczególnymi elementami tablicy. Typ parametru jest obiektem.

parameters:
- name: myArray
  type: object
  default:
    - FOO
    - BAR
    - ZOO

variables:
   A: ${{ join(';',parameters.myArray) }}

steps:
  - script: echo $A # outputs FOO;BAR;ZOO

Le

  • Ocenia, czy lewy True parametr jest mniejszy lub równy prawego parametru
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Błędy w przypadku niepowodzenia konwersji.
  • Porządkowe porównanie przypadków dla ciągów.
  • Przykład: le(2, 2) (zwraca wartość True)

długość

  • Zwraca długość ciągu lub tablicy, która pochodzi z systemu lub pochodzi z parametru
  • Parametry minimalne: 1. Parametry maksymalne: 1.
  • Przykład: length('fabrikam') zwraca wartość 8.

dolny

  • Konwertuje ciąg lub wartość zmiennej na wszystkie małe litery.
  • Parametry minimalne: 1. Parametry maksymalne: 1.
  • Zwraca ciąg znaków w postaci małych liter.
  • Przykład: lower('FOO') zwraca wartość foo.

Lt

  • Ocenia, czy lewy True parametr jest mniejszy niż właściwy parametr.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Błędy w przypadku niepowodzenia konwersji.
  • Porównanie ciągów bez uwzględniania wielkości liter.
  • Przykład: lt(2, 5) (zwraca wartość True)

Ne

  • True Ocenia, czy parametry nie są równe
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Konwertuje prawy parametr na zgodny typ lewego parametru. Zwraca wartość True w przypadku niepowodzenia konwersji.
  • Porównanie porządkowe bez uwzględniania wielkości liter dla ciągów znaków.
  • Przykład: ne(1, 2) zwraca wartość True.

nie

  • Ocenia True, czy parametr jest False
  • Minimalne parametry: 1. Maksymalna liczba parametrów: 1
  • Konwertuje wartość na wartość logiczną na potrzeby oceny
  • Przykład: not(eq(1, 2)) (zwraca wartość True)

notIn (nie)

  • Ocenia, czy lewy True parametr nie jest równy żadnemu właściwemu parametrowi
  • Minimalne parametry: 1. Maksymalna liczba parametrów: N
  • Konwertuje prawe parametry na zgodny typ lewego parametru. Ocena równości sprawdza False w przypadku niepowodzenia konwersji.
  • Porównanie porządkowe z ignorowaniem wielkości liter dla ciągów znaków.
  • Krótkie spięcia po pierwszym dopasowaniu
  • Przykład: notIn('D', 'A', 'B', 'C') (zwraca wartość True)

lub

  • True Ocenia, czy którykolwiek parametr jest True
  • Parametry minimalne: 2. Maksymalna liczba parametrów: N.
  • Rzutuje parametry na wartość logiczną na potrzeby oceny.
  • Zwarcia po pierwszym True
  • Przykład: or(eq(1, 1), eq(2, 3)) (zwraca wartość True, zwarcie)

zamienić

  • Zwraca nowy ciąg, w którym wszystkie wystąpienia ciągu w bieżącym wystąpieniu są zastępowane innym ciągiem.
  • Parametry minimalne: 3. Maksymalna liczba parametrów: 3.
  • replace(a, b, c): zwraca a, ze wszystkimi wystąpieniami b zastąpionymi przez c.
  • Przykład: replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server') (zwraca wartość http://server/saml/consume).

podzielić

  • Dzieli ciąg na podciągi na podstawie określonych znaków ograniczników.
  • Parametry minimalne: 2. Parametry maksymalne: 2.
  • Pierwszy parametr to ciąg do podzielenia.
  • Drugi parametr to znaki rozdzielania.
  • Zwraca tablicę podciągów. Tablica zawiera puste ciągi, gdy znaki rozdzielające występują kolejno lub na końcu tekstu.
  • Przykład:
    variables:
    - name: environments
      value: prod1,prod2
    steps:
      - ${{ each env in split(variables.environments, ',')}}:
        - script: ./deploy.sh --environment ${{ env }}
    
  • Przykład użycia funkcji split() z funkcją replace():
    parameters:
    - name: resourceIds
      type: object
      default:
      - /subscriptions/mysubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/loadBalancers/kubernetes-internal
      - /subscriptions/mysubscription02/resourceGroups/myResourceGroup02/providers/Microsoft.Network/loadBalancers/kubernetes
    - name: environments
      type: object
      default:
      - prod1
      - prod2
    
    trigger:
    - main
    
    steps:
    - ${{ each env in parameters.environments }}:
      - ${{ each resourceId in parameters.resourceIds }}:
          - script: echo ${{ replace(split(resourceId, '/')[8], '-', '_') }}_${{ env }}
    

zaczyna się od

  • Ocenia, czy lewy ciąg parametru True rozpoczyna się od prawego parametru
  • Minimalne parametry: 2. Parametry maksymalne: 2.
  • Rzutuje parametry na ciąg znaków w celu oceny.
  • Wykonuje porządkowe porównanie przypadków ignorowania.
  • Przykład: startsWith('ABCDE', 'AB') (zwraca wartość True).

przycinać

  • Zwraca parametr bez wiodących i końcowych białych znaków.
  • Minimalne parametry: 1. Maksymalna liczba parametrów: 1
  • Przykład: trim(' variable ') zwraca zmienną

górny

  • Konwertuje wartość ciągu lub zmiennej na wszystkie wielkie litery
  • Parametry minimalne: 1. Parametry maksymalne: 1.
  • Zwraca wersję ciągu znaków w wielkich literach
  • Przykład: upper('bah') zwraca BAH

Xor

  • Ocenia True, czy dokładnie jeden parametr jest True
  • Minimalne parametry: 2. Parametry maksymalne: 2.
  • Rzutuje parametry na wartość logiczną na potrzeby oceny.
  • Przykład: xor(True, False) (zwraca wartość True)

Funkcje sprawdzania stanu zadania

Użyj następujących funkcji sprawdzania stanu jako wyrażeń w warunkach, ale nie w definicjach zmiennych.

zawsze

  • Zawsze przyjmuje wartość True (nawet w przypadku anulowania). Uwaga: Błąd krytyczny może nadal uniemożliwiać uruchomienie zadania. Na przykład jeśli pobieranie źródeł nie powiodło się.

Anulowane

  • Ocena wynosi True, jeśli potok zostanie anulowany.

niepowodzenie

  • Dla kroku, równoważny eq(variables['Agent.JobStatus'], 'Failed').
  • W przypadku pracy
    • Bez argumentów wartościuje do True, jeśli którekolwiek z wcześniejszych zadań na wykresie zależności nie powiodło się.
    • Funkcja zwraca True w przypadku nazw zadań jako argumentów, jeśli którekolwiek z tych zadań nie powiodło się.

Powiodło się

  • Dla kroku, równoważny in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues').
  • Używaj dependsOn podczas pracy z zadaniami, kiedy chcesz sprawdzić, czy poprzednie zadanie zakończyło się pomyślnie. Zadania są uruchamiane równolegle, a etapy są uruchamiane sekwencyjnie.
  • W przypadku pracy
    • Bez argumentów zwraca True, jeśli wszystkie poprzednie zadania w grafie zależności zakończyły się powodzeniem lub częściowym powodzeniem.
    • W przypadku nazw zadań jako argumentów True ocenia, czy wszystkie te zadania zakończyły się powodzeniem, czy częściowo powiodło się.
    • Ocena wynosi False, jeśli potok zostanie anulowany.

powiodło się lub nie powiodło

  • Dla kroku, równoważny in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed').

  • W przypadku pracy

    • Bez argumentów funkcja ocenia True niezależnie od tego, czy jakiekolwiek zadania w grafie zależności zakończyły się powodzeniem, czy niepowodzeniem.
    • W przypadku nazw zadań jako argumentów True ocenia, czy którekolwiek z tych zadań zakończyło się powodzeniem, czy niepowodzeniem.
    • Zamiast tego warto użyć not(canceled()) , gdy poprzednie zadania na grafie zależności zostaną pominięte.

    Ta funkcja jest podobna do always(), z tą różnicą, że równa się False gdy potok zostanie anulowany.

Wstawianie warunkowe

Użyj klauzul if, elseif i else, aby warunkowo przypisać wartości zmiennych lub ustawić dane wejściowe dla zadań. Można również warunkowo uruchomić krok, jeśli zostanie spełniony warunek.

Warunkowe działają tylko wtedy, gdy używasz składni szablonu. Aby uzyskać więcej informacji, zobacz składnię zmiennych.

W przypadku szablonów można użyć wstawiania warunkowego podczas dodawania sekwencji lub mapowania. Aby uzyskać więcej informacji, zobacz wstawianie warunkowe w szablonach.

Warunkowe przypisywanie zmiennej

variables:
  ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: # only works if you have a main branch
    stageName: prod

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo ${{variables.stageName}}

Warunkowe ustawianie danych wejściowych zadania

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)'
    ${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
      artifact: 'prod'
    ${{ else }}:
      artifact: 'dev'
    publishLocation: 'pipeline'

Warunkowe uruchamianie kroku

Jeśli nie ma ustawionej zmiennej lub wartość foo nie jest zgodna z if warunkami, else instrukcja zostaje wykonana. W tym przykładzie wartość foo zwraca wartość true w warunku elseif.

variables:
  - name: foo
    value: contoso # triggers elseif condition

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo "start"
- ${{ if eq(variables.foo, 'adaptum') }}:
  - script: echo "this is adaptum"
- ${{ elseif eq(variables.foo, 'contoso') }}: # true
  - script: echo "this is contoso"
- ${{ else }}:
  - script: echo "the value is not adaptum or contoso"

Każde słowo kluczowe

Użyj słowa kluczowego each , aby przeprowadzić pętlę przez parametry z typem obiektu.

parameters:
- name: listOfStrings
  type: object
  default:
  - one
  - two

steps:
- ${{ each value in parameters.listOfStrings }}:
  - script: echo ${{ value }}

Można również iterować po zagnieżdżonych elementach w obiekcie.

parameters:
- name: listOfFruits
  type: object
  default:
  - fruitName: 'apple'
    colors: ['red','green']
  - fruitName: 'lemon'
    colors: ['yellow']
steps:
- ${{ each fruit in parameters.listOfFruits }} :
  - ${{ each fruitColor in fruit.colors}} :
    - script: echo ${{ fruit.fruitName}} ${{ fruitColor }}

Zależności

Wyrażenia mogą używać kontekstu zależności, aby odwoływać się do poprzednich zadań lub etapów. Użyj zależności, aby:

  • Odwołaj się do statusu poprzedniego zadania
  • Odwołuje się do stanu poprzedniego etapu
  • Odwołuj się do zmiennych wyjściowych w poprzednim zadaniu na tym samym etapie
  • Odwołanie do zmiennych wyjściowych z poprzedniego etapu w obecnym etapie.
  • Odwołuj się do zmiennych wyjściowych zadania z poprzedniego etapu w następnym etapie.

Kontekst jest określany jako dependencies dla zadań i etapów i działa podobnie jak zmienne. Jeśli odwołujesz się do zmiennej wyjściowej z zadania na innym etapie, kontekst jest nazywany stageDependencies.

Jeśli występują problemy ze zmiennymi wyjściowymi z znakami cudzysłowu (' lub ") w nich, zapoznaj się z tym przewodnikiem rozwiązywania problemów.

Omówienie składni zależności

Składnia odwoływania się do zmiennych wyjściowych z zależnościami różni się w zależności od okoliczności. Oto omówienie najbardziej typowych scenariuszy. Czasami składnia alternatywna również działa.

Rodzaj

Opis

Odnieś się do zmiennej wyjściowej z poprzedniej fazy w zadaniu w innym etapie w warunku w stages.

  • Składnia: and(succeeded(), eq(stageDependencies.<stage-name>.outputs['<job-name>.<step-name>.<variable-name>'], 'true'))
  • Przykład: and(succeeded(), eq(stageDependencies.A.outputs['A1.printvar.shouldrun'], 'true'))

zależność pomiędzy zadaniami (w tym samym etapie)

Odwołaj się do zmiennej wyjściowej w innym zadaniu w tej samej fazie w stages.

  • Składnia: and(succeeded(), eq(dependencies.<job-name>.outputs['<step-name>.<variable-name>'], 'true'))
  • Przykład: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))

Odwołanie do zmiennej wynikowej na innym etapie w job.

  • Składnia: eq(stageDependencies.<stage-name>.<job-name>.outputs['<step-name>.<variable-name>'], 'true')
  • Przykład: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')

Relacje między etapami (praca wdrożeniowa)

Odwołanie do zmiennej wyjściowej w zadaniu wdrożenia na innym etapie w stages.

  • Składnia: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<deployment-job-name>.<step-name>.<variable-name>'], 'true')
  • Przykład: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')

Zależność etapu do etapu (zadanie wdrożenia z zasobami)

Odwołuje się do zmiennej wyjściowej w zadaniu wdrażania, która zawiera zasób na innym etapie w programie stages.

  • Składnia: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<Deploy_resource-name>.<step-name>.<variable-name>'], 'true')
  • Przykład: eq(dependencies.build.outputs['build_job.Deploy_winVM.setRunTests.runTests'], 'true')

Składnia zmiennych wyjściowych w zadaniach wdrażania różni się w zależności od strategii wdrażania. Aby uzyskać więcej informacji, zobacz Zadania wdrażania.

Zależności między etapami

Zasadniczo obiekt dependencies jest mapą przypisującą nazwy zadań i etapów do results i outputs. Wygląda na to, że jest wyrażona w formacie JSON:

"dependencies": {
  "<STAGE_NAME>" : {
    "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
    "outputs": {
        "jobName.stepName.variableName": "value"
    }
  },
  "...": {
    // another stage
  }
}

Uwaga

W poniższych przykładach użyto standardowej składni potoku. Jeśli używasz potoków wdrożeniowych, składnia zmiennych i zmiennych warunkowych różni się. Aby uzyskać informacje o określonej składni do użycia, zobacz Zadania wdrażania.

Użyj tej formy dependencies , aby mapować zmienne lub sprawdzać warunki na poziomie etapu.

W tym przykładzie istnieją dwa etapy: A i B. Etap A ma warunek false i nie jest uruchamiany. Etap B jest uruchamiany, jeśli wynik etapu A to Succeeded, SucceededWithIssueslub Skipped. Etap B jest realizowany, ponieważ etap A został pominięty.

stages:
- stage: A
  condition: false
  jobs:
  - job: A1
    steps:
    - script: echo Job A1
- stage: B
  condition: in(dependencies.A.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
  jobs:
  - job: B1
    steps:
    - script: echo Job B1

Etapy mogą również używać zmiennych wyjściowych z innego etapu. W tym przykładzie istnieją dwa etapy. Etap A obejmuje zadanie A1, które ustawia zmienną shouldrun wyjściową na true. Etap B jest uruchamiany, gdy shouldrun ma wartość true. Ze względu na shouldrun, true etap B jest uruchamiany.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
  dependsOn: A
  jobs:
  - job: B1
    steps:
    - script: echo hello from Stage B

Uwaga

Domyślnie każdy etap w potoku zależy od tego, który go bezpośrednio poprzedza w pliku YAML. Jeśli musisz odwołać się do etapu, który nie jest bezpośrednio przed bieżącym etapem, możesz zastąpić tę automatyczną wartość domyślną, dodając sekcję dependsOn do etapu.

Zależności między zadaniami w ramach jednego etapu

Na poziomie zadania w ramach jednego etapu dane dependencies nie zawierają informacji na poziomie etapu.

"dependencies": {
  "<JOB_NAME>": {
    "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
    "outputs": {
      "stepName.variableName": "value1"
    }
  },
  "...": {
    // another job
  }
}

W tym przykładzie istnieją trzy zadania (a, b i c). Zadanie a jest zawsze pomijane z powodu elementu condition: false. Zadanie b działa, ponieważ nie ma powiązanych warunków. Zadanie c jest uruchamiane, ponieważ wszystkie jego zależności kończą się powodzeniem (zadanie b) lub są pomijane (zadanie a).

jobs:
- job: a
  condition: false
  steps:
  - script: echo Job a
- job: b
  steps:
  - script: echo Job b
- job: c
  dependsOn:
  - a
  - b
  condition: |
    and
    (
      in(dependencies.a.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
      in(dependencies.b.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
    )
  steps:
  - script: echo Job c

W tym przykładzie zadanie B zależy od zmiennej wyjściowej z zadania A.

jobs:
- job: A
  steps:
  - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
  # or on Windows:
  # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
    name: printvar

- job: B
  condition: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))
  dependsOn: A
  steps:
  - script: echo hello from B

Zależności między zadaniami w różnych etapach

Na poziomie zadania można również odwoływać się do danych wyjściowych z zadania w poprzednim etapie. Wymaga to użycia stageDependencies kontekstu.

"stageDependencies": {
  "<STAGE_NAME>" : {
    "<JOB_NAME>": {
      "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
      "outputs": {
          "stepName.variableName": "value"
      }
    },
    "...": {
      // another job
    }
  },
  "...": {
    // another stage
  }
}

W tym przykładzie zadanie B1 jest uruchamiane, jeśli zadanie A1 zostanie pominięte. Zadanie B2 sprawdza wartość zmiennej wyjściowej z zadania A1, aby określić, czy ma zostać uruchomiona.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  dependsOn: A
  jobs:
  - job: B1
    condition: in(stageDependencies.A.A1.result, 'Skipped') # change condition to `Succeeded and stage will be skipped`
    steps:
    - script: echo hello from Job B1
  - job: B2
    condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
    steps:
     - script: echo hello from Job B2

Jeśli zadanie zależy od zmiennej zdefiniowanej przez zadanie wdrożenia na innym etapie, składnia jest inna. W poniższym przykładzie zadanie run_tests jest uruchamiane, jeśli zadanie wdrożenia build_job zostało ustawione na runTeststrue. Zwróć uwagę, że kluczem używanym dla słownika outputs jest build_job.setRunTests.runTests.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: Production
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  jobs:
    - job: run_tests
      condition: eq(stageDependencies.build.build_job.outputs['build_job.setRunTests.runTests'], 'true')
      steps:
        ...

Zmienne wyjściowe zadania wdrożenia

Jeśli etap zależy od zmiennej zdefiniowanej przez zadanie wdrożenia na innym etapie, składnia jest inna. W poniższym przykładzie etap test zależy od ustawienia wdrożenia build_job tak, by shouldTest było true. Zwróć uwagę, że w condition etapie testbuild_job pojawia się dwa razy.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: Production
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  condition: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')
  jobs:
    - job: A
      steps:
        - script: echo Hello from job A

W powyższym przykładzie warunek odwołuje się do środowiska, a nie zasobu środowiska. Aby odwołać się do zasobu środowiska, należy dodać nazwę zasobu środowiska do warunku zależności. W poniższym przykładzie warunek odwołuje się do zasobu maszyny wirtualnej środowiska o nazwie vmtest.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: vmtest
      resourceName: winVM2
      resourceType: VirtualMachine
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  condition: eq(dependencies.build.outputs['build_job.Deploy_winVM2.setRunTests.runTests'], 'true')
  jobs:
  - job: A
    steps:
     - script: echo Hello from job A

Filtrowane tablice

Podczas pracy z kolekcją elementów użyj * składni, aby zastosować filtrowaną tablicę. Filtrowana tablica zwraca wszystkie obiekty lub elementy niezależnie od ich nazw.

Rozważmy na przykład tablicę obiektów o nazwie foo. Chcesz uzyskać tablicę wartości id właściwości w każdym obiekcie w tablicy.

[
    { "id": 1, "a": "avalue1"},
    { "id": 2, "a": "avalue2"},
    { "id": 3, "a": "avalue3"}
]

Użyj następującego wyrażenia:

foo.*.id

To wyrażenie nakazuje systemowi traktowanie foo jako filtrowanej tablicy, a następnie wybranie id właściwości z każdego obiektu.

To wyrażenie zwraca:

[ 1, 2, 3 ]

Rzutowanie typów

Wartości w wyrażeniu mogą być konwertowane z jednego typu na inny, gdy wyrażenie zostanie obliczone. Podczas oceniania wyrażenia proces konwertuje parametry na odpowiedni typ danych, a następnie zamienia je z powrotem w ciągi.

Na przykład w tym YAML wartości True i False zamieniają się na 1 i 0 gdy wyrażenie jest oceniane. Funkcja lt() zwraca True wartość , gdy lewy parametr jest mniejszy niż prawy parametr.

variables:
  firstEval: $[lt(False, True)] # 0 vs. 1, True
  secondEval: $[lt(True, False)] # 1 vs. 0, False

steps:
- script: echo $(firstEval)
- script: echo $(secondEval)

Jeśli używasz eq() wyrażenia do obliczania równoważności, wartości są niejawnie konwertowane na liczby (false na 0 i true do 1).

variables:
  trueAsNumber: $[eq('true', true)] # 1 vs. 1, True
  falseAsNumber: $[eq('false', true)] # 0 vs. 1, False

steps:
- script: echo $(trueAsNumber)
- script: echo $(falseAsNumber)

W następnym przykładzie wartości variables.emptyString i pusty ciąg są obliczane jako puste ciągi. Funkcja coalesce() oblicza parametry w kolejności i zwraca pierwszą wartość, która nie ma wartości null ani pustego ciągu.

variables:
  coalesceLiteral: $[coalesce(variables.emptyString, '', 'literal value')]

steps:
- script: echo $(coalesceLiteral) # outputs literal value

Szczegółowe reguły konwersji zostały wymienione poniżej.

Od / Do logiczny Null (zero) Liczba Sznurek Wersja
Wartość logiczna - - Tak Tak -
Zero Tak - Tak Tak -
Liczba Tak - - Tak Częściowe
ciąg Tak Częściowe Częściowe - Częściowe
Wersja Tak - - Tak -

logiczny

Do numerowania:

  • False0
  • True1

Na ciąg:

  • False'False'
  • True'True'

Null (zero)

  • Na Boolean: False
  • Do numeru: 0
  • Do ciągu: '' (pusty ciąg)

Liczba

  • Do wartości logicznej: 0False, dowolna inna liczba → True
  • Wersja: musi być większa niż zero i musi zawierać niezerową liczbę dziesiętną. Musi być mniejsza niż Int32.MaxValue (składnik dziesiętny).
  • Do ciągu: Konwertuje liczbę na ciąg bez separatora tysięcy i bez separatora dziesiętnego.

Sznurek

  • Do wartości logicznej: '' (pusty ciąg) → False, dowolny inny ciąg → True
  • Do wartości null: '' (pusty ciąg) → Null, każdy inny ciąg, którego nie można przekonwertować.
  • Aby numerować: '' (pusty ciąg) → 0, w przeciwnym razie uruchamia język C# Int32.TryParse przy użyciu metody InvariantCulture i następujące reguły: AllowDecimalPoint | AllowLeadingSign | AllowLeadingWhite | AllowThousands | AllowTrailingWhite. Jeśli TryParse się nie powiedzie, to nie można go przekonwertować.
  • Do wersji: uruchamia C# Version.TryParse. Powinien zawierać co najmniej główny i drugorzędny składnik. Jeśli TryParse się nie powiedzie, to nie można go przekonwertować.

Wersja

  • Na Boolean: True
  • Ciąg: Major.Minor lub Major.Minor.Build lub Major.Minor.Build.Revision.

Często zadawane pytania

Chcę zrobić coś, czego wyrażenia nie przewidują. Jakie mam opcje rozszerzenia funkcjonalności Pipelines?

Można dostosować pipeline przy użyciu skryptu zawierającego wyrażenie. Na przykład ten fragment kodu pobiera zmienną BUILD_BUILDNUMBER i dzieli ją przy użyciu powłoki Bash. Ten skrypt zwraca dwie nowe zmienne: $MAJOR_RUN i $MINOR_RUN, które reprezentują główne i pomocnicze numery przebiegów. Dwie zmienne są następnie używane do tworzenia dwóch zmiennych $major i $minor potoku za pomocą task.setvariable. Te zmienne są dostępne dla kroków podrzędnych. Aby współużytkować zmienne w potokach, zobacz Grupy zmiennych.

steps:
- bash: |
    MAJOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f1)
    echo "This is the major run number: $MAJOR_RUN"
    echo "##vso[task.setvariable variable=major]$MAJOR_RUN"

    MINOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
    echo "This is the minor run number: $MINOR_RUN"
    echo "##vso[task.setvariable variable=minor]$MINOR_RUN"

- bash: echo "My pipeline variable for major run is $(major)"
- bash: echo "My pipeline variable for minor run is $(minor)"