Как реализовать условное утверждение во время выполнения в конвейерах Azure DevOps?
Мне нужно настроить задание в Azure DevOps, которое требует утверждения только тогда, когда переменная времени выполнения имеет определенное значение. Согласно документации, утверждения оцениваются во время компиляции, что означает, что даже если мое условие возвращает false, утверждение все равно требуется для запуска задания, даже если задание не выполняет никаких действий.
Существует ли обходное решение для реализации условных утверждений во время выполнения в конвейерах Azure DevOps?
Условное утверждение во время выполнения в конвейерах Azure DevOps
Условное утверждение во время выполнения в конвейерах Azure DevOps представляет значительный вызов из-за способа оценки условий в Azure Pipelines. Хотя прямой поддержки для условных утверждений нет, несколько эффективных обходных решений могут обеспечить аналогичную функциональность.
Azure Pipelines оценивает условия до выполнения конвейера, что означает, что переменные времени выполнения нельзя использовать непосредственно в условиях утверждения. В документации Microsoft Learn явно указано: “Условия оцениваются для определения, следует ли запускать этап, задание или шаг. Поэтому ничего, вычисленное во время выполнения этапа, задания или шага, недоступно для использования в этом же этапе, задании или шаге.”
Вот наиболее эффективные обходные решения для реализации условных утверждений во время выполнения:
Содержание
- Понимание основной проблемы
- Обходное решение 1: Переменные зависимостей этапов
- Обходное решение 2: Логика на основе параметров
- Обходное решение 3: Ручные утверждения для заданий без агента
- Обходное решение 4: Условные этапы на основе шаблонов
- Рекомендации и лучшие практики
- Альтернативные подходы
- Заключение
Понимание основной проблемы
Azure Pipelines использует систему двухфазной оценки:
- Оценка во время компиляции: Условия оцениваются до выполнения для определения того, что должно быть запущено
- Оценка во время выполнения: Переменные и выражения оцениваются во время выполнения
Это разделение означает, что переменные, установленные во время выполнения, не могут влиять на решения, принятые во время компиляции, такие как необходимость утверждения. Как объясняется в официальной документации, “если вы устанавливаете переменную в задании с помощью выражения времени выполнения с синтаксисом $[ ], вы не можете использовать эту переменную в условиях внутри этого же задания.”
Обходное решение 1: Переменные зависимостей этапов
Наиболее надежный подход - использовать переменные зависимостей этапов для передачи информации во время выполнения между этапами и принятия решений об утверждении на основе этих значений.
stages:
- stage: evaluation_stage
jobs:
- job: determine_approval
steps:
- task: PowerShell@2
name: set_approval_flag
inputs:
targetType: inline
pwsh: true
script: |
$requireApproval = $true # Логика для определения необходимости утверждения
echo "##vso[task.setvariable variable=needApproval;isOutput=true]$requireApproval"
- stage: deployment_stage
dependsOn: evaluation_stage
condition: eq(dependencies.evaluation_stage.outputs['determine_approval.set_approval_flag.needApproval'], 'true')
jobs:
- deployment: deploy_job
environment: production
strategy:
runOnce:
deploy:
steps:
- task: ManualIntervention@0
name: manual_approval
inputs:
instructions: 'Пожалуйста, проверьте и утвердите это развертывание'
Этот подход работает потому, что:
- Сначала выполняется этап оценки и вычисляется требование к утверждению
- Результат передается как выходная переменная
- Условие этапа развертывания проверяет это значение перед решением о запуске
- Если условие истинно, выполняется шлюз утверждения
Согласно блогу Black Marble, “ручные утверждения для заданий без агента оцениваются после условия задания, поэтому не страдают от той же проблемы.”
Обходное решение 2: Логика на основе параметров
Использование параметров с оценкой во время выполнения может обеспечить условное поведение, хотя с некоторыми ограничениями:
parameters:
- name: requireApproval
type: boolean
default: false
stages:
- stage: deployment
condition: eq('${{ parameters.requireApproval }}', 'true')
jobs:
- deployment: deploy_job
environment: production
strategy:
runOnce:
deploy:
steps:
- task: ManualIntervention@0
inputs:
instructions: 'Требуется ручное утверждение'
Чтобы это работало во время выполнения, можно использовать REST API Azure DevOps или Azure CLI для установки значения параметра:
az pipelines run --parameters requireApproval=true --branch main
Этот подход ограничен, поскольку параметры обычно устанавливаются до выполнения, но он может работать в сочетании с соответствующими значениями по умолчанию и внешней логикой.
Обходное решение 3: Ручные утверждения для заданий без агента
Для заданий развертывания можно использовать задания без агента с ручными утверждениями, которые оцениваются после условия задания:
stages:
- stage: conditional_approval
jobs:
- deployment: deploy_with_approval
environment: production
pool: none # Задание без агента
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: check_conditions
inputs:
targetType: inline
pwsh: true
script: |
# Оценка условия во время выполнения
$shouldApprove = $true # Ваша логика здесь
if ($shouldApprove) {
echo "##vso[task.logissue type=warning]Требуется ручное утверждение"
echo "##vso[task.complete result=SucceededWithIssues;]"
} else {
echo "##vso[task.complete result=Succeeded;]"
}
- task: ManualIntervention@0
condition: eq(dependencies['deploy_with_approval'].result, 'SucceededWithIssues')
inputs:
instructions: 'Пожалуйста, проверьте и утвердите это развертывание'
Этот подход использует тот факт, что задания без агента не страдают от тех же ограничений оценки условий, что и обычные задания.
Обходное решение 4: Условные этапы на основе шаблонов
Использование шаблонов с условными выражениями позволяет обеспечить более гибкую логику утверждений:
# templates/conditional-approval.yml
parameters:
- name: approvalRequired
type: boolean
default: false
stages:
- stage: deploy
condition: eq('${{ parameters.approvalRequired }}', 'true')
jobs:
- deployment: deploy_job
environment: production
strategy:
runOnce:
deploy:
steps:
- task: ManualIntervention@0
inputs:
instructions: 'Требуется ручное утверждение'
# Основной конвейер
stages:
- template: templates/conditional-approval.yml
parameters:
approvalRequired: true
Этот подход позволяет динамически включать или исключать этапы утверждений на основе условий времени выполнения.
Рекомендации и лучшие практики
На основе результатов исследования, вот ключевые рекомендации:
- Используйте переменные зависимостей этапов: Это наиболее надежный подход для условных утверждений
- Разделяйте логику оценки: Создавайте выделенные этапы/задания для вычисления условий перед принятием решений об утверждении
- Используйте задания без агента: Для сценариев развертывания задания без агента с ручными утверждениями работают хорошо
- Планируйте архитектуру конвейера: Проектируйте ваш конвейер с учетом условного выполнения с самого начала
В документации Microsoft Learn подчеркивается: “Вам необходимо присвоить значение по умолчанию в вашем YAML-файле или при запуске конвейера. Если вы не присваиваете значение по умолчанию или устанавливаете default в false, используется первое доступное значение.”
Альтернативные подходы
Если приведенные выше обходные решения не соответствуют вашим требованиям, рассмотрите эти альтернативы:
Внешняя служба утверждений
Интегрируйтесь с внешней службой утверждений, которая может принимать решения на основе условий времени выполнения и запускать выполнение конвейера соответственно.
Многоконвейерный подход
Разделите ваше развертывание на отдельные конвейеры:
- Конвейер, который оценивает условия и устанавливает соответствующие переменные
- Второй конвейер, который выполняется на основе этих переменных и включает логику утверждений
Интеграция с Azure Policy
Используйте Azure Policy для управления разрешениями на развертывание на основе условий, которые могут быть оценены во время выполнения.
Заключение
Хотя Azure DevOps не поддерживает условные утверждения во время выполнения нативно, существует несколько эффективных обходных решений:
- Переменные зависимостей этапов - Наиболее надежный подход для сложных сценариев
- Логика на основе параметров - Проще, но с ограничениями
- Утверждения для заданий без агента - Идеально для заданий развертывания
- Условные этапы на основе шаблонов - Гибкие и повторно используемые
Ключевым является разделение оценки условий от выполнения утверждений, использование системы зависимостей Azure Pipelines для передачи информации во время выполнения между этапами конвейера. Как отметил один участник Stack Overflow: “Хотя Шайки прав, что это не поддерживается - существует обходное решение, которое я в настоящее время использую.”
Для критически важных сценариев рассмотрите возможность сочетания этих подходов с внешними системами утверждений или разделения процесса на несколько конвейеров для достижения желаемого поведения условного утверждения.
Источники
- Условия конвейера - Azure Pipelines | Microsoft Learn
- Использование переменных зависимостей этапов Azure DevOps с условным выполнением этапа и задания | Black Marble
- Условное выполнение этапа в конвейерах Azure DevOps - Stack Overflow
- Условной шлюз утверждения в заданиях развертывания в azure pipelines - Stack Overflow
- Условные этапы, задания и шаги в YAML Azure DevOps - CloudShift
- Выражения - Azure Pipelines | Microsoft Learn
- Условное выполнение для этапа - Azure DevOps - GeralexGR
- Использование параметров времени выполнения и безопасных по типу - Azure Pipelines | Microsoft Learn