Определение условий
Azure DevOps Services | Azure DevOps Server 2022 г. - Azure DevOps Server 2019 г. | TFS 2018
Вы можете указать условия, при которых выполняется каждый из этапов, заданий или шагов. По умолчанию задание или этап выполняется, если они не зависят от какого-либо другого задания или этапа либо если все задания или этапы, от которых они зависят, завершены и успешно завершены. Сюда входят не только прямые зависимости, но и их зависимости, которые вычисляются рекурсивно. По умолчанию шаг выполняется, если в его задании не произошло никакого сбоя, а шаг, непосредственно предшествующий ему, завершен. Вы можете настроить это поведение, принудительно запустив этап, задание или шаг, даже если предыдущая зависимость завершилась сбоем, или указав пользовательское условие.
Примечание
В Microsoft Team Foundation Server (TFS) 2018 и предыдущих версий конвейеры сборки и выпуска называются определениями, выполнения называются сборками, подключения к службам называются конечными точками служб, этапы называются средами, а задания называются этапами.
Вы можете указать условия, при которых будет выполняться шаг, задание или этап.
Только при успешном выполнении всех предыдущих прямых и косвенных зависимостей с тем же пулом агентов. Если у вас разные пулы агентов, эти этапы или задания будут выполняться одновременно. Это значение по умолчанию, если в YAML не задано условие.
Даже если произошел сбой предыдущей зависимости, если запуск не отменен. Используйте
succeededOrFailed()
в YAML для этого условия.Даже если произошел сбой предыдущей зависимости и даже если запуск отменен. Используйте
always()
в YAML для этого условия.Только после сбоя предыдущей зависимости. Используйте
failed()
в YAML для этого условия.
- Настраиваемые условия
По умолчанию шаги, задания и этапы выполняются, если все предыдущие шаги или задания выполнены успешно. Это так, как если бы вы указали "condition: succeeded()" (см . раздел Функции состояния задания).
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
Переменные также можно использовать в условиях.
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)
Условия оцениваются, чтобы решить, следует ли начать этап, задание или шаг.
Это означает, что ничего, вычисленное во время выполнения в этой единице работы, не будет доступно.
Например, если у вас есть задание, которое задает переменную с помощью выражения среды выполнения с помощью $[ ]
синтаксиса, эту переменную нельзя использовать в пользовательском условии.
YAML не поддерживается в TFS.
Примечание
При указании собственного condition
свойства для этапа, задания или шага его значение по умолчанию condition: succeeded()
перезаписывается. Это может привести к выполнению этапа, задания или шага, даже если сборка отменена. При написании собственных условий обязательно учитывайте состояние родительского этапа или задания.
Включение настраиваемого условия
Если встроенные условия не соответствуют вашим потребностям, можно указать пользовательские условия.
Условия записываются в виде выражений в конвейерах YAML. Агент вычисляет выражение, начиная с самой внутренней функции, и прорабатывает свой путь. Конечным результатом является логическое значение, определяющее, должны ли выполняться задача, задание или этап. Полное руководство по синтаксису см. в статье о выражениях .
Любое из ваших условий позволяет выполнять задачу даже после отмены сборки пользователем? Если это так, укажите разумное значение времени ожидания отмены , чтобы у таких задач было достаточно времени для выполнения после отмены выполнения пользователем.
Поведение конвейера при отмене сборки
Отмена сборки не означает, что все ее этапы, задания или шаги перестают выполняться. Решение зависит от указанного этапа, задания или шага conditions
и от того, в какой точке выполнения конвейера вы отменили сборку.
Если условие не учитывает состояние родительского элемента вашего этапа, задания или шага, то, если условие имеет значение true
, будет выполняться ваш этап, задание или шаг, даже если его родительский элемент отменен. Если его родительский элемент пропущен, этап, задание или шаг не будут выполняться.
Рассмотрим несколько примеров.
В этом конвейере по умолчанию stage2
зависит от stage1
и stage2
имеет condition
набор. stage2
Выполняется, только если исходная ветвь имеет значение 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
Если вы ставите сборку в очередь в main
ветвь и отменяете ее во время stage1
выполнения, stage2
будет по-прежнему true
выполняться, так как eq(variables['Build.SourceBranch'], 'refs/heads/main')
имеет значение .
В этом конвейере stage1
зависит от stage2
. Задание B
имеет condition
набор для него.
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
Если вы ставите сборку в очередь в main
ветвь и отменяете ее во время stage1
выполнения, stage2
не будет выполняться, даже если она содержит задание A
, условие которого оценивается как true
. Причина заключается в том, что stage2
имеет значение по умолчанию condition: succeeded()
, которое имеет false
значение при stage1
отмене. Таким образом, stage2
пропускается, и ни одно из его заданий не выполняется.
Предположим, у вас есть следующий конвейер YAML. Обратите внимание, что по умолчанию stage2
зависит от stage1
и , script: echo 2
для которого condition
задано значение .
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')
Если вы ставите сборку main
в очередь в ветвь и отменяете ее во время stage1
выполнения, stage2
не будет выполняться, даже если она содержит шаг в задании B
, условие которого оценивается как true
. Причина в том, что stage2
пропускается в ответ на отмену stage1
.
Чтобы предотвратить выполнение этапов, заданий или шагов с conditions
при отмене сборки, убедитесь, что при записи учитывается состояние родительского conditions
элемента . Дополнительные сведения см. в разделе Функции состояния задания.
Примеры
Запуск для главной ветви, даже если она отменена, даже в случае сбоя
eq(variables['Build.SourceBranch'], 'refs/heads/main')
Выполните команду для главной ветви, если она выполнена успешно
and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
Выполните команду , если ветвь не является основной, если она выполнена успешно
and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
Выполнение для ветвей пользовательских разделов, если оно выполнено успешно
and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
Выполнение для сборок непрерывной интеграции (CI) при успешном выполнении
and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
Запуск, если сборка выполняется политикой ветви для запроса на вытягивание, если не удается
and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
Запуск, если сборка запланирована, даже в случае сбоя, даже в случае отмены
eq(variables['Build.Reason'], 'Schedule')
Release.Artifacts. {artifact-alias}. SourceBranch эквивалентен Build.SourceBranch.
Всегда выполняется, если переменная имеет значение true, даже если отменена, даже если произошел сбой.
eq(variables['System.debug'], true)
Выполняется, если переменная имеет значение NULL (пустая строка)
Так как в Azure Pipelines все переменные обрабатываются как строки, пустая строка эквивалентна null
в этом конвейере.
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
Использование параметра шаблона как части условия
Когда вы объявляете параметр в том же конвейере, что и условие, расширение параметра происходит до того, как будут рассмотрены условия. В этом случае вы можете встроить параметры в условия. Скрипт в этом ФАЙЛЕ YAML будет выполняться, так как parameters.doThing
имеет значение true.
в condition
конвейере объединяет две функции: succeeded()
и eq('${{ parameters.doThing }}', true)
. Функция succeeded()
проверяет, успешно ли выполнен предыдущий шаг. Функция succeeded()
возвращает значение true, так как предыдущего шага не было.
Функция eq('${{ parameters.doThing }}', true)
проверяет, равен true
ли параметр doThing . Так как значение по умолчанию для doThing равно true, условие возвращает значение true по умолчанию, если в конвейере не заданы другие значения.
Дополнительные примеры параметров шаблона см. в разделе Использование типов шаблонов&.
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), eq('${{ parameters.doThing }}', true))
При передаче параметра в шаблон необходимо задать значение параметра в шаблоне или использовать templateContext для передачи свойств в шаблоны.
# 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: ${{ if eq(parameters.doThing, true) }}
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
Выходные данные этого конвейера обусловлены I did a thing
тем, что параметр doThing
имеет значение true.
Использование выходной переменной из задания в условии в последующем задании
Вы можете сделать переменную доступной для будущих заданий и указать ее в условии. Переменные, доступные для будущих заданий, должны быть помечены как выходные переменные с несколькими заданиями с помощью 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."
Использование переменной конвейера, созданной на шаге, в условии на последующем шаге
Вы можете сделать переменную доступной для будущих шагов и указать ее в условии. По умолчанию переменные, созданные на шаге, доступны для будущих шагов и не нужно помечать как выходные переменные с несколькими заданиями с помощью isOutput=true
.
Существует несколько важных моментов, которые следует отметить в отношении приведенного выше подхода и области.
- Переменные, созданные на шаге задания, будут ограничены шагами в том же задании.
- Переменные, созданные на шаге, будут доступны только на последующих этапах в качестве переменных среды.
- Переменные, созданные на шаге, нельзя использовать на шаге, который их определяет.
Ниже приведен пример создания переменной конвейера на шаге и использования переменной в условии и скрипте последующего шага.
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'))
Вопросы и ответы
Как я могу активировать задание, если предыдущее задание было выполнено с проблемами?
Вы можете использовать результат предыдущего задания. Например, в этом YAML-файле условие eq(dependencies.A.result,'SucceededWithIssues')
позволяет выполнять задание, так как задание A успешно выполнено с проблемами.
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
Я отменил свою сборку, но она все еще работает. В чем причина?
Эта проблема возникает, если условие, настроенное на этапе, не включает функцию проверки состояния задания. Чтобы устранить эту проблему, добавьте в условие функцию проверки состояния задания. Если вы отмените задание, пока оно находится в очереди, но не выполняется, все задание будет отменено, включая все остальные этапы.
Узнайте больше о поведении конвейера при отмене сборки.