Поделиться через


Выражения

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

Внимание

Выберите версию в селекторе версии содержимого Azure DevOps.

Выберите версию этой статьи, соответствующую вашей платформе и версии. Селектор версий находится над оглавлением. Просмотрите платформу и версию Azure DevOps.

Выражения можно использовать во многих местах, где необходимо указать строковое, логическое или числовое значение при создании конвейера. Когда выражение возвращает массив, применяются обычные правила индексирования и индекс начинается с 0.

Наиболее распространенное использование выражений находится в условиях , чтобы определить, следует ли выполнять задание или шаг.

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

Другое частое использование выражений заключается в определении переменных. Выражения можно оценивать во время компиляции или во время выполнения. Выражения времени компиляции можно использовать в любом месте; Выражения среды выполнения можно использовать в переменных и условиях. Выражения среды выполнения предназначены для вычисления содержимого переменных и состояний (например: 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> ]

Разница между синтаксисами выражений времени выполнения и компиляции состоит в первую очередь в том, какой контекст доступен. В выражении времени компиляции (${{ <expression> }}) у вас есть доступ к parameters и статически определенному variables. В выражении среды выполнения ($[ <expression> ]) у вас есть доступ к большему variables , но не к параметрам.

В этом примере выражение среды выполнения задает значение $(isMain). Статическую переменную в выражении компиляции задает значение $(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

Выражение может быть литеральным, ссылкой на переменную, ссылкой на зависимость, функцию или допустимое вложенное сочетание этих значений.

Литералы

В рамках выражения можно использовать логические, null, число, строки или литералы версии.

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

Логический

True и False являются логическими литеральными выражениями.

Null

Null — это специальное литеральное выражение, возвращаемое из пропущенного словаря, например (variables['noSuch']). Null может быть выходным результатом выражения, но не может вызываться непосредственно в выражении.

Число

Начинается с "-", "." или "0" до "9".

Строка

Должен быть одинарным. Например: 'this is a string'.

Чтобы выразить литеральный одинарный кавычки, избежать его с помощью одной кавычки. Например: 'It''s OK if they''re using contractions.'.

Для многостроковых строк можно использовать символ канала (|).

myKey: |
  one
  two
  three

Версия

Номер версии до четырех сегментов. Должен начинаться с числа и содержать два или три символа (.). Например: 1.2.3.4.

Переменные

В рамках выражения можно получить доступ к переменным с помощью одного из двух синтаксисов:

  • Синтаксис индексов: variables['MyVar']
  • Синтаксис разыменования свойств: variables.MyVar

Чтобы использовать синтаксис разыменования свойств, имя свойства должно

  • Начните с a-Z или _
  • За ним следует a-Z 0-9 или _

В зависимости от контекста выполнения доступны разные переменные.

Переменные всегда являются строками. Если вы хотите использовать типизированные значения, вместо этого следует использовать параметры .

Примечание.

Существует ограничение на использование переменных с выражениями для классических и yamL конвейеров при настройке таких переменных с помощью пользовательского интерфейса вкладки переменных. Переменные, определенные как выражения, не должны зависеть от другой переменной с выражением в значении, так как они не гарантируют правильное вычисление обоих выражений. Например, у нас есть переменная a , значение $[ <expression> ] которой используется в качестве части значения переменной b. Так как порядок обработки переменных не гарантируется, что переменная может иметь неправильное значение переменной b a после оценки.

Описанные конструкции разрешены только при настройке переменных с помощью ключевого слова переменных в конвейере YAML. Необходимо разместить переменные в порядке их обработки, чтобы получить правильные значения после обработки.

Функции

Следующие встроенные функции можно использовать в выражениях.

и

  • Вычисляется, True если все параметры являются True
  • Минимальные параметры: 2. Максимальные параметры: N
  • Приведение параметров к логическому значению для оценки
  • Короткие цепи после первого False
  • Пример: and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))

coalesce

  • Вычисляет параметры в порядке (слева направо) и возвращает первое значение, которое не равно null или пустой строке.
  • Значение не возвращается, если все значения параметров имеют значение NULL или пустые строки.
  • Минимальные параметры: 2. Максимальные параметры: N
  • Пример: coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')

содержит

  • Вычисляет, True содержит ли левая строка параметра правую строку
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Приведение параметров к Строке для оценки
  • Выполняет порядковое сравнение без учета регистра
  • Пример: contains('ABCDE', 'BCD') (возвращает значение True)

containsValue

  • Вычисляет True , является ли левый параметр массивом, а любой элемент равен правому параметру. Также вычисляется True , является ли левый параметр объектом, а значение любого свойства равно правому параметру.
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Если левый параметр является массивом, преобразуйте каждый элемент в соответствии с типом правого параметра. Если левый параметр является объектом, преобразуйте значение каждого свойства в соответствии с типом правого параметра. Сравнение равенства для каждого конкретного элемента оценивается, если преобразование завершается False ошибкой.
  • Сравнение порядкового регистра для строк
  • Короткие цепи после первого матча

Примечание.

В конвейере YAML нет литерального синтаксиса для указания массива. Эта функция имеет ограниченное использование в общих конвейерах. Он предназначен для использования в контексте декоратора конвейера с системными массивами, такими как список шагов.

Выражение можно использовать containsValue для поиска соответствующего значения в объекте. Ниже приведен пример, демонстрирующий поиск в списке исходных ветвей для соответствия 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

  • Возьмите сложный объект и выводит его в формате JSON.
  • Минимальные параметры: 1. Максимальные параметры: 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) }}

Выходные данные скрипта:

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

людей Irisys

  • Эта функция может использоваться только в выражении, определяющем переменную. Его нельзя использовать как часть условия для шага, задания или этапа.
  • Вычисляет число, которое увеличивается при каждом запуске конвейера.
  • Параметры: 2. prefix и seed.
  • Префикс — это строковое выражение. Отдельное значение счетчика отслеживается для каждого уникального значения префикса. Он prefix должен использовать символы UTF-16.
  • Начальное значение счетчика — это начальное значение счетчика

Вы можете создать счетчик, который автоматически увеличивается по одному в каждом выполнении конвейера. При определении счетчика необходимо указать prefix и .seed Ниже приведен пример, демонстрирующий это.

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)

Значение minor в приведенном выше примере в первом запуске конвейера равно 100. Во втором запуске значение равно 101, если значение major по-прежнему равно 1.

Если изменить файл YAML и обновить значение переменной major до 2, то в следующем запуске конвейера значение minor будет равно 100. Последующие запуски увеличивают счетчик до 101, 102, 103, ...

Позже, если изменить файл YAML и задать значение major 1, значение счетчика возобновляется, где оно осталось для этого префикса. В этом примере оно возобновляется в 102 году.

Ниже приведен еще один пример задания переменной для действия в качестве счетчика, который начинается с 100, увеличивается на 1 для каждого запуска и получает сброс до 100 каждый день.

Примечание.

pipeline.startTime недоступно вне выражений. pipeline.startTime форматирует system.pipelineStartTime объект даты и времени, чтобы он работал с выражениями. Часовой пояс pipeline.startTime по умолчанию — UTC. Вы можете изменить часовой пояс для вашей организации.

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

Ниже приведен пример наличия счетчика, который поддерживает отдельное значение для PR и выполнения CI.

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

Счетчики ограничены конвейером. Другими словами, его значение увеличивается для каждого запуска этого конвейера. Счетчики с областью действия проекта отсутствуют.

endsWith

  • Вычисляет True , заканчивается ли строка слева с правым параметром
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Приведение параметров к Строке для оценки
  • Выполняет порядковое сравнение без учета регистра
  • Пример: endsWith('ABCDE', 'DE') (возвращает значение True)

eq

  • Вычисляет True , равны ли параметры
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Возвращается, если преобразование завершается False ошибкой.
  • Сравнение порядкового регистра для строк
  • Пример: eq(variables.letters, 'ABC')

format

  • Вычисляет конечные параметры и вставляет их в строку ведущих параметров.
  • Минимальные параметры: 1. Максимальные параметры: N
  • Пример: format('Hello {0} {1}', 'John', 'Doe')
  • Использует настраиваемые описатели формата даты и времени .NET для форматирования дат (yyyy, MfffffffsyyssmmMMHdddHHm) K
  • Пример: format('{0:yyyyMMdd}', pipeline.startTime). В этом случае pipeline.startTime это специальная переменная объекта времени даты.
  • Побег, удвоив фигурные скобки. Например: format('literal left brace {{ and literal right brace }}')

ge

  • Вычисляется True , превышает ли левый параметр или равен правому параметру.
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Ошибки при сбое преобразования.
  • Сравнение порядкового регистра для строк
  • Пример: ge(5, 5) (возвращает значение True)

gt

  • Вычисляет True , больше ли левый параметр, чем правый параметр
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Ошибки при сбое преобразования.
  • Сравнение порядкового регистра для строк
  • Пример: gt(5, 2) (возвращает значение True)

in

  • Вычисляется, True равен ли левый параметр любому правому параметру
  • Минимальные параметры: 1. Максимальные параметры: N
  • Преобразует правые параметры в тип левого параметра. Сравнение равенства оценивается, если преобразование завершается False ошибкой.
  • Сравнение порядкового регистра для строк
  • Короткие цепи после первого матча
  • Пример: in('B', 'A', 'B', 'C') (возвращает значение True)

join

  • Объединяет все элементы в правом массиве параметров, разделенные строкой слева.
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Каждый элемент в массиве преобразуется в строку. Сложные объекты преобразуются в пустую строку.
  • Если правильный параметр не является массивом, результатом является правильный параметр, преобразованный в строку.

В этом примере точка с запятой добавляется между каждым элементом в массиве. Тип параметра — это объект.

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

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

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

le

  • Вычисляет True , равен ли левый параметр меньше или равен правому параметру
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Ошибки при сбое преобразования.
  • Сравнение порядкового регистра для строк
  • Пример: le(2, 2) (возвращает значение True)

length

  • Возвращает длину строки или массива, которая поступает из системы или из параметра.
  • Минимальные параметры: 1. Максимальные параметры 1
  • Пример: length('fabrikam') возвращает 8

lower

  • Преобразует строковое или переменное значение во все строчные символы
  • Минимальные параметры: 1. Максимальные параметры 1
  • Возвращает строчные буквы, эквивалентные строке
  • Пример: lower('FOO') возвращается foo

lt

  • Вычисляет True , меньше ли левый параметр, чем правый параметр
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Ошибки при сбое преобразования.
  • Сравнение порядкового регистра для строк
  • Пример: lt(2, 5) (возвращает значение True)

ne

  • Вычисляет True , не равны ли параметры
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Преобразует правый параметр в тип левого параметра. Возвращается, если преобразование завершается True ошибкой.
  • Сравнение порядкового регистра для строк
  • Пример: ne(1, 2) (возвращает значение True)

not

  • Вычисляет True , является ли параметр False
  • Минимальные параметры: 1. Максимальные параметры: 1
  • Преобразует значение в логическое значение для оценки
  • Пример: not(eq(1, 2)) (возвращает значение True)

NotIn

  • Вычисляет True , не равен ли левый параметр любому правому параметру
  • Минимальные параметры: 1. Максимальные параметры: N
  • Преобразует правые параметры в тип левого параметра. Сравнение равенства оценивается, если преобразование завершается False ошибкой.
  • Сравнение порядкового регистра для строк
  • Короткие цепи после первого матча
  • Пример: notIn('D', 'A', 'B', 'C') (возвращает значение True)

or

  • Вычисляет True , является ли какой-либо параметр True
  • Минимальные параметры: 2. Максимальные параметры: N
  • Приведение параметров к логическому значению для оценки
  • Короткие цепи после первого True
  • Пример: or(eq(1, 1), eq(2, 3)) (возвращает значение True, короткие цепи)

replace

  • Возвращает новую строку, в которой все экземпляры строки в текущем экземпляре заменяются другой строкой.
  • Минимальные параметры: 3. Максимальные параметры: 3
  • replace(a, b, c): возвращает значение, причем все экземпляры b заменены на c
  • Пример: replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server') (возвращается http://server/saml/consume)

split

  • Разбивает строку на подстроки на основе указанных символов разделителя
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Первый параметр — это строка для разделения
  • Второй параметр — символы разделителя
  • Возвращает массив подстроок. Массив включает пустые строки, когда символы разделителя отображаются последовательно или в конце строки
  • Пример:
    variables:
    - name: environments
      value: prod1,prod2 
    steps:  
      - ${{ each env in split(variables.environments, ',')}}:
        - script: ./deploy.sh --environment ${{ env }}
    
  • Пример использования split() с 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 }}
    

startsWith

  • Вычисляет, True начинается ли строка слева с правого параметра
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Приведение параметров к Строке для оценки
  • Выполняет порядковое сравнение без учета регистра
  • Пример: startsWith('ABCDE', 'AB') (возвращает значение True)

upper

  • Преобразует строковое или переменное значение во все символы верхнего регистра
  • Минимальные параметры: 1. Максимальные параметры 1
  • Возвращает эквивалент строки в верхнем регистре.
  • Пример: upper('bah') возвращается BAH

xor

  • Вычисляет True , является ли ровно один параметр True
  • Минимальные параметры: 2. Максимальные параметры: 2
  • Приведение параметров к логическому значению для оценки
  • Пример: xor(True, False) (возвращает значение True)

Функции проверки состояния задания

Следующие функции проверки состояния можно использовать в качестве выражений в условиях, но не в определениях переменных.

всегда

  • Всегда вычисляется True (даже при отмене). Примечание. Критический сбой может по-прежнему препятствовать выполнению задачи. Например, если не удалось получить источники.

отменено

  • Оценивается, True если конвейер был отменен.

ошибка

  • Для шага, эквивалентного eq(variables['Agent.JobStatus'], 'Failed').
  • Для задания:
    • Без аргументов оценивается True только в случае сбоя предыдущего задания в граф зависимостей.
    • С именами заданий в качестве аргументов оценивается True только в том случае, если одно из этих заданий завершилось ошибкой.

Выполнено

  • Для шага, эквивалентного in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
  • Используется при dependsOn работе с заданиями и вы хотите оценить, успешно ли выполнено предыдущее задание. Задания предназначены для параллельного выполнения во время последовательного выполнения этапов.
  • Для задания:
    • Без аргументов оценивается True только в том случае, если все предыдущие задания в граф зависимостей успешно или частично выполнены.
    • При использовании имен заданий в качестве аргументов вычисляется, True если все эти задания успешно выполнены или частично выполнены.
    • Оценивается, False если конвейер отменен.

успешно выполненоOrFailed

  • Для шага, эквивалентного in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed')

  • Для задания:

    • Без аргументов оценивается True независимо от того, выполнены ли какие-либо задания в граф зависимостей успешно или неудачно.
    • При использовании имен заданий в качестве аргументов оценивается True , успешно ли выполнено любое из этих заданий или завершилось сбоем.
    • Вместо этого может потребоваться использовать not(canceled()) предыдущие пропущенные задания в граф зависимостей.

    Это похоже always(), за исключением того, что он будет оцениваться False при отмене конвейера.

Условное вставка

Можно использовать ifelseifelse и предложения для условного назначения значений переменных или задания входных данных для задач. При выполнении условия можно также выполнить шаг условно.

Можно использовать if для условного назначения значений переменных или задания входных данных для задач. При выполнении условия можно также выполнить шаг условно.

else Предложения elseif и предложения доступны начиная с Azure DevOps 2022 и недоступны для Azure DevOps Server 2020 и более ранних версий Azure DevOps.

Условные условия работают только при использовании синтаксиса шаблона. Дополнительные сведения о синтаксисе переменных.

Для шаблонов можно использовать условное вставка при добавлении последовательности или сопоставления. Дополнительные сведения об условной вставке в шаблонах.

Условно назначьте переменную

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}}

Условно задать входные данные задачи

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'

Условное выполнение шага

Если переменная не задана или значение foo не соответствует if условиям, else инструкция выполняется. Здесь значение foo true в условии 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"

Каждое ключевое слово

Ключевое each слово можно использовать для цикла параметров с типом объекта.

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

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

Кроме того, можно итерировать вложенные элементы в объекте.

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 }}

Зависимости

Выражения могут использовать контекст зависимостей для ссылки на предыдущие задания или этапы. Для этого можно использовать зависимости:

  • Ссылка на состояние задания предыдущего задания
  • Ссылка на состояние этапа предыдущего этапа
  • Ссылочные выходные переменные в предыдущем задании на том же этапе
  • Ссылки на выходные переменные на предыдущем этапе на этапе
  • Ссылка на выходные переменные задания на предыдущем этапе на следующем этапе

Контекст вызывается dependencies для заданий и этапов и работает так же, как переменные. Если вы ссылаетесь на выходную переменную из задания на другом этапе, вызывается stageDependenciesконтекст.

Если возникают проблемы с выходными переменными с символами кавычки (' или ") в них, ознакомьтесь с этим руководством по устранению неполадок.

Общие сведения о синтаксисе зависимостей

Синтаксис ссылки на выходные переменные с зависимостями зависит от обстоятельств. Ниже приведен обзор наиболее распространенных сценариев. Иногда также работает альтернативный синтаксис.

Тип

Description

этап к этапу зависимости (разные этапы)

Ссылка на выходную переменную из предыдущего этапа задания в другом этапе в условии stages.

  • Синтаксис: and(succeeded(), eq(stageDependencies.<stage-name>.outputs['<job-name>.<step-name>.<variable-name>'], 'true'))
  • Пример: and(succeeded(), eq(stageDependencies.A.outputs['A1.printvar.shouldrun'], 'true'))

задание зависимости задания (один и тот же этап)

Ссылка на выходную переменную в другом задании на том же этапе stages.

  • Синтаксис: and(succeeded(), eq(dependencies.<job-name>.outputs['<step-name>.<variable-name>'], 'true'))
  • Пример: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))

Задание для этапов зависимости (различные этапы)

Ссылка на выходную переменную на другом этапе.job

  • Синтаксис: eq(stageDependencies.<stage-name>.<job-name>.outputs['<step-name>.<variable-name>'], 'true')
  • Пример: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')

Этап к этапу зависимости (задание развертывания)

Ссылка на переменную выходных данных в задании развертывания на другом этапе stages.

  • Синтаксис: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<deployment-job-name>.<step-name>.<variable-name>'], 'true')
  • Пример: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')

Этап к этапу зависимости (задание развертывания с ресурсом)

Ссылка на выходную переменную в задании развертывания, включающую ресурс на другом этапе stages.

  • Синтаксис: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<Deploy_resource-name>.<step-name>.<variable-name>'], 'true')
  • Пример: eq(dependencies.build.outputs['build_job.Deploy_winVM.setRunTests.runTests'], 'true')

Существуют также различные синтаксисы выходных переменных в заданиях развертывания в зависимости от стратегии развертывания. Дополнительные сведения см. в разделе "Задания развертывания".

Этап к этапу зависимостей

dependencies Структурно объект — это карта имен заданий и этапов с results иoutputs. Выражение в формате JSON будет выглядеть следующим образом:

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

Примечание.

В следующих примерах используется стандартный синтаксис конвейера. Если вы используете конвейеры развертывания, оба синтаксиса переменных и условной переменной будут отличаться. Сведения об используемом синтаксисе см. в разделе "Задания развертывания".

Используйте эту форму dependencies для сопоставления переменных или проверки условий на уровне этапа.

В этом примере есть два этапа, А и B. Этап A имеет условие false и никогда не будет выполняться в результате. Этап B выполняется, если результат этапа A имеет Succeededзначение , SucceededWithIssuesили Skipped. Этап B выполняется, так как этап A пропущен.

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

Этапы также могут использовать выходные переменные из другого этапа. В этом примере также существует два этапа. Этап A включает задание A1, которое задает для выходной переменной shouldrun trueзначение . Этап B выполняется при shouldrun выполнении true. Так как shouldrun выполняется trueэтап B.

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

Примечание.

По умолчанию каждый этап в конвейере зависит от одного непосредственно перед ним в YAML-файле. Если вам нужно ссылаться на этап, который не находится непосредственно перед текущим, можно переопределить этот автоматический параметр по умолчанию, добавив dependsOn раздел на этап.

Задание зависимостей заданий на одном этапе

На уровне задания на одном этапе данные не содержат сведения о уровне стадии dependencies .

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

В этом примере есть три задания (a, b и c). Задание всегда пропускается из-за condition: false. Задание b выполняется из-за отсутствия связанных условий. Задание c выполняется из-за успешного выполнения всех зависимостей (задание b) или пропускается (задание 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

В этом примере задание B зависит от выходной переменной задания 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

Задание зависимостей заданий на разных этапах

На уровне задания можно также ссылаться на выходные данные задания на предыдущем этапе. Для этого требуется использование контекста stageDependencies .

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

В этом примере задание B1 выполняется, если задание A1 пропущено. Задание B2 проверяет значение выходной переменной из задания A1, чтобы определить, следует ли выполнять ее.

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

Если задание зависит от переменной, определенной заданием развертывания на другом этапе, синтаксис отличается. В следующем примере задание run_tests выполняется, если build_job для задания развертывания задано значение truerunTests . Обратите внимание, что ключ, используемый для outputs словаря 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:
        ...

Выходные переменные задания развертывания

Если этап зависит от переменной, определенной заданием развертывания на другом этапе, синтаксис отличается. В следующем примере этап test зависит от параметра shouldTest trueразвертыванияbuild_job. Обратите внимание, что на condition test этапе build_job отображается дважды.

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

В приведенном выше примере условие ссылается на среду, а не ресурс среды. Чтобы ссылаться на ресурс среды, необходимо добавить имя ресурса среды в условие зависимостей. В следующем примере условие ссылается на ресурс виртуальной машины среды с именем 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

Отфильтрованные массивы

При работе с коллекцией элементов можно использовать * синтаксис для применения отфильтрованного массива. Отфильтрованный массив возвращает все объекты и элементы независимо от их имен.

Например, рассмотрим массив объектов с именем foo. Мы хотим получить массив значений id свойства в каждом объекте в нашем массиве.

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

Мы могли бы сделать следующее:

foo.*.id

Это указывает системе работать в foo качестве отфильтрованного массива, а затем выбрать id свойство.

Будет возвращено следующее:

[ 1, 2, 3 ]

Приведение типов

Значения в выражении могут быть преобразованы из одного типа в другой по мере вычисления выражения. При вычислении выражения параметры объединяются с соответствующим типом данных, а затем возвращаются в строки.

Например, в этом YAML значения True и False преобразуются 1 в и 0 при вычислении выражения. Функция lt() возвращается True , если левый параметр меньше справа.

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

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

В этом примере значения variables.emptyString и пустая строка оцениваются как пустые строки. Функция coalesce() вычисляет параметры в порядке и возвращает первое значение, которое не равно null или пустой строке.

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

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

Ниже перечислены подробные правила преобразования.

От / В Логический Null Число Строка Версия
Boolean - - Да Да -
Null Да - Да Да -
Число Да - - Да Частично
String Да Частично Частично - Частично
Версия Да - - Да -

Логический

Число:

  • False0
  • True1

Строка:

  • False'False'
  • True'True'

Null

  • Для логических значений: False
  • Число: 0
  • Строка: '' (пустая строка)

Число

  • Для boolean: 0False, любое другое число → True
  • Для версии: должно быть больше нуля и должно содержать ненулевое десятичное значение. Должно быть меньше Int32.MaxValue (десятичный компонент также).
  • Для строки: преобразует число в строку без разделителя тысяч и без десятичного разделителя.

Строка

  • Логическое значение: '' (пустая строка) → False, любая другая строка → True
  • Значение NULL: '' (пустая строка) → Null, любая другая строка не преобразуемая
  • Число: '' (пустая строка) → 0, в противном случае выполняется C# Int32.TryParse с помощью invariantCulture и следующих правил: AllowDecimalPoint | AllowLeadingSign | AllowLeadingWhite | AllowThousands | AllowTrailingWhite. В случае TryParse сбоя он не преобразуется.
  • Для версии: выполняет C# Version.TryParse. Должен содержать как минимум основной и дополнительный компонент. В случае TryParse сбоя он не преобразуется.

Версия

  • Для логических значений: True
  • Строка: Major.Minor или Major.Minor.Build или Major.Minor.Build.Revision.

Вопросы и ответы

Я хочу сделать то, что не поддерживается выражениями. Какие параметры доступны для расширения функциональных возможностей Конвейеров?

Конвейер можно настроить с помощью скрипта, включающего выражение. Например, этот фрагмент принимает BUILD_BUILDNUMBER переменную и разделяет ее с помощью Bash. Этот скрипт выводит две новые переменные, $MAJOR_RUN а $MINOR_RUNтакже для основных и дополнительных чисел выполнения. Затем эти две переменные используются для создания двух переменных $major конвейера и $minor с помощью task.setvariable. Эти переменные доступны для нижестоящих шагов. Сведения о совместном доступе к переменным в конвейерах см . в группах переменных.

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