Определение условий

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

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

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

  • Только если все предыдущие прямые и косвенные зависимости с тем же пулом агентов успешно выполнены. Если у вас разные пулы агентов, эти этапы или задания будут выполняться одновременно. Это значение по умолчанию, если в YAML не задано условие.

  • Даже если предыдущая зависимость не завершилась ошибкой, если выполнение не было отменено. Используйте succeededOrFailed() в YAML для этого условия.

  • Даже если предыдущая зависимость завершилась ошибкой, даже если выполнение было отменено. Используйте always() в YAML для этого условия.

  • Только при сбое предыдущей зависимости. Используйте failed() в YAML для этого условия.

  • Настраиваемые условия

По умолчанию шаги, задания и этапы выполняются, если все прямые и косвенные зависимости выполнены успешно. Это так, как если бы вы указали "условие: успешно()" (см . функцию успешного состояния).

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 зависит от stage1stage2condition набора. 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 так как eq(variables['Build.SourceBranch'], 'refs/heads/main') оценивается true.

В этом конвейере stage2 зависит от stage1. Задание 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даже если она содержит заданиеB, условие которого оценивается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, условие возвращается по умолчанию, если в конвейере не задано другое значение.

Дополнительные примеры параметров шаблона см. в разделе "Типы шаблонов" и "Использование".

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

steps:
- script: echo I did a thing
  condition: ${{ 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: ${{ 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') позволяет выполнять задание, так как задание успешно выполнено с проблемами.

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

Я отменил свою сборку, но она все еще работает. Что происходит?

Эта проблема возникает, если условие, настроенное на этапе, не включает состояние задания проверка функцию. Чтобы устранить проблему, добавьте в условие состояние задания проверка функцию. Если вы отменяете задание во время его выполнения, но не выполняется, все задание отменяется, включая все остальные этапы.

Узнайте больше о поведении конвейера при отмене сборки.