Почему мои условия не работают должным образом в конвейерах YAML Azure DevOps при использовании условий на основе динамической переменной?

Я создаю сценарий выпуска YAML для Azure DevOps. Я все еще тестирую, как отличить триггер вручную/другой конвейерный триггер от триггера, поступающего из веб-перехватчика, и как условно выполнить некоторую другую логику (например, разные утверждения,...).

В настоящее время у меня есть следующий YAML:

trigger: none
resources:
  pipelines:
  - pipeline: buildPipeline
    source: 'POC - Build'
    trigger:
      branches:
        include:
        - develop
  webhooks:
    - webhook: Trigger
      connection: Connection
      filters:
        - path: ReleaseName
          value: Plugins

variables:
  - name: isAutomatedTrigger
    value: $[
              and(
                eq(variables['Build.reason'], 'ResourceTrigger'),
                eq(variables['resources.triggeringAlias'], 'KristaDeploymentTrigger')
              )
            ]

stages:
  - stage: Test
    jobs:
    - job:
      steps:
      - checkout: none
      - ${{if eq(variables.isAutomatedTrigger, True)}}:
        - script: echo 'This is an automated trigger'
      - ${{else}}:
        - script: echo 'This is not an automated trigger'

Когда я выполняю скрипт, запуская его вручную в DevOps, DevOps показывает мне, что параметр isAutomatedTrigger имеет значение False. Когда я запускаю скрипт с помощью веб-перехватчика, DevOps показывает мне, что параметр имеет значение true.

Однако в обеих ситуациях печатается текст «Это не автоматический триггер».

Я пробовал разные варианты написания True, true, 'True', ...

Я пробовал не использовать eq (just if (variables.isAutomatedTrigger), ..., но ничего не помогает. Я также попробовал разные обозначения переменных: variables['isAutomatedTrigger'].

Иногда результат меняется: и ручной триггер, и триггер веб-перехватчика конвейера приводят к выводу «Это автоматический триггер», но они никогда не ведут себя должным образом, даже если параметр всегда оценивается правильно.

Привет @BastiaanSmis! Есть ли у вас возможность проверить ответы ниже, чтобы использовать свойство условия вместо условных вставок? Надеюсь, информация в этом посте поможет решить вашу проблему. Спасибо.

Alvin Zhao - MSFT 17.07.2024 11:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема

Ваша переменная устанавливается с использованием выражения времени выполнения $[ ... ]:

variables:
  - name: isAutomatedTrigger
    value: $[ ... ]

Но вы пытаетесь использовать его в выражении шаблона ${{ ... }}, которое обрабатывается во время компиляции до начала выполнения:

${{ if eq(variables.isAutomatedTrigger, True) }}

Это никогда не сработает, поскольку значение isAutomatedTrigger неизвестно до компиляции конвейера.

Дополнительную информацию см. в разделе Понимание синтаксиса переменных.

Обходной путь

Используйте условия вместо шаблонных выражений:

variables:
  - name: buildReasonAndAlias
    value: "$(Build.Reason)-$(resources.triggeringAlias)"

steps:
  - script: |
      echo "This is an automated trigger"

      echo "buildReasonAndAlias: $(buildReasonAndAlias)"
      echo "Build.Reason: ${{ variables['Build.Reason'] }}"
      echo "resources.triggeringAlias: $(resources.triggeringAlias)"
    displayName: Display variables when on triggered run
    condition: and(succeeded(), eq(variables['buildReasonAndAlias'], 'ResourceTrigger-KristaDeploymentTrigger'))

  - script: |
      echo "This is not an automated trigger"

      echo "buildReasonAndAlias: $(buildReasonAndAlias)"
      echo "Build.Reason: ${{ variables['Build.Reason'] }}"
      echo "resources.triggeringAlias: $(resources.triggeringAlias)"
    displayName: Display variables when on manual run
    condition: and(succeeded(), ne(variables['buildReasonAndAlias'], 'ResourceTrigger-KristaDeploymentTrigger'))
Ответ принят как подходящий

Согласно схеме Ресурсы, когда ресурс запускает конвейер, устанавливаются следующие переменные:

resources.triggeringAlias
resources.triggeringCategory

Переменная Build.Reason должна быть ResourceTrigger, чтобы эти значения были установлены. Значения пусты, если ресурс не инициировал запуск конвейера. Эти переменные доступны вашему конвейеру только во время выполнения.

Поэтому мы можем оценивать такие переменные ресурсов только в выражениях времени выполнения , а не во время компиляции шаблонных выражениях , таких как условные вставки (${{if}}), которые обрабатываются во время компиляции перед временем выполнения.

В дополнение к четкому и явному ответу @RUI, переменная $(resources.triggeringAlias) будет расширена как символическое имя запускающего ресурса, то есть buildPipeline или Trigger с учетом вашего образца; и нам не нужно оценивать, является ли $(Build.Reason)ResourceTrigger, если $(resources.triggeringAlias) не пусто.

Вот пример конвейера YAML для справки.

trigger: none
resources:
  pipelines:
  - pipeline: buildPipeline
    source: 'POC - Build'
    trigger:
      branches:
        include:
        - develop
  webhooks:
    - webhook: Trigger
      connection: Connection
      filters:
        - path: ReleaseName
          value: Plugins

variables:
  - name: isAutomatedTrigger
    value: $[
              and(
                eq(variables['Build.Reason'], 'ResourceTrigger'),
                eq(variables['resources.triggeringAlias'], 'buildPipeline')
              )
            ]

stages:
  - stage: Test
    jobs:
    - job:
      steps:
      - checkout: none
      - script: |
          echo "================ This is an automated trigger by resource =============== = "
          echo "Build.Reason is $(Build.Reason)"
          echo "triggeringAlias is $(resources.triggeringAlias)"
          echo "resources.triggeringCategory is $(resources.triggeringCategory)"

          echo "================ Is Automated Trigger? - $(isAutomatedTrigger) =============== = "
        condition: or(
                      eq(variables['resources.triggeringAlias'], 'buildPipeline'),
                      eq(variables['resources.triggeringAlias'], 'Trigger')
                    )
      - script: echo 'This is not an automated trigger'
        condition: eq(variables['resources.triggeringAlias'], '')

Другие вопросы по теме