¿Cómo puedo usar IF ELSE en las variables de la tubería yaml de DevOps azul con grupo variable?

8

Estoy tratando de asignar uno de los 2 valores a una variable además del grupo de variables y no puedo encontrar la referencia de cómo usar IF ELSE.

Básicamente, necesito convertir esta lógica de jerkins a DevOps azul.

Jenkins

if (branch = 'master') { 
   env = 'a'
} else if (branch = 'dev'){
    env ='b'
}

Encontré 1 referencia de la siguiente, pero esta parece funcionar si la sección de variables no tiene grupos de variables.

https://stackoverflow.com/a/57532526/5862540

Pero en mi cartera, ya tengo un grupo variable para secretos, así que tengo que usar la convención de nombre / valor y el ejemplo no funciona con los errores como expected a mappingo A mapping was not expectedoUnexpected value 'env'

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: 
      env: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: 
      env: b

o

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: b

kevmando
fuente
Una solución alternativa que tengo ahora es que copio la sección de variables con expresión en todos los trabajos donde necesito. Pero me gustaría hacerlo simple variable global.
kevmando

Respuestas:

1

Creo que por ahora necesitará usar una tarea para personalizar con name/valuevariables de sintaxis y valores de variables condicionales. Parece que la estructura del objeto para la name/valuesintaxis rompe el análisis de las expresiones, como usted ha señalado.

Para mí, lo siguiente es una implementación razonablemente limpia, y si desea abstraerlo de la tubería, parece que una plantilla simple para que use sus muchas tuberías debería satisfacer el deseo de una ubicación central "global".

variables:
  - group: FakeVarGroup
  - name: env
    value: dev

steps:
  - powershell: |
      if ($env:Build_SourceBranchName -eq 'master') {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]a
        return
      } else {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]b
      }      
    displayName: "Set Env Value"
Josh Gust
fuente
Gracias por la sugerencia Creo que había visto una solución similar desde aquí, pero no lo he intentado porque espero que haya una solución más simple sin agregar un paso. También pedí soporte de MS, así que si no tienen solución, intentaré esto.
kevmando
Intercambié correos electrónicos con soporte de MS y terminaron sugiriendo esta solución y me pidieron que ingresara sugerencias de características para la comunidad de desarrollo de MS. Así que marcaré esto como respuesta ahora.
kevmando
0

Hasta donde sé, la mejor manera de tener una construcción de rama condicional es usar "trigger" en su YAML, en lugar de implementar "if-else" complejo. También es mucho más seguro y tiene controles más explícitos sobre los desencadenantes de la rama en lugar de depender de las variables de CI.

Ejemplo:

# specific branch build 
jobs:
- job: buildmaster
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - master

  steps:
  - script: |
      echo "trigger for master branch"

- job: buildfeature
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - feature

  steps:
  - script: |
      echo "trigger for feature branch"

Para tener un activador con inclusión y exclusión de ramas, puede usar una sintaxis más compleja de activador con incluir y excluir ramas.

Ejemplo:

# specific branch build
trigger:
  branches:
    include:
    - master
    - releases/*
    exclude:
    - releases/1.*

La documentación oficial de Azure DevOps Pipelines triggeren YAML es: Documentación de activación de Azure Pipelines YAML

ACTUALIZACIÓN 1 :

Vuelvo a publicar mi comentario aquí con notas adicionales: estaba pensando en tener diferentes canales porque tener la complejidad de hacer malabarismos entre las variables de CI no es más fácil de mantener que tener múltiples trabajos en un YAML con disparadores. Tener múltiples trabajos con disparadores también nos obliga a tener una clara distinción y provisión en la gestión de sucursales. Mi equipo ha utilizado disparadores e inclusiones de ramas condicionales durante un año debido a estas ventajas de mantenibilidad.

No dude en estar en desacuerdo, pero para mí tener una lógica incrustada en cualquier secuencia de comandos en cualquier paso para verificar qué rama está actualmente en sesión y luego realiza cualquier otra acción, son más como soluciones ad-hoc. Y esto nos ha dado a mi equipo y a mí problemas de mantenimiento antes.

Especialmente si la lógica incrustada tiende a crecer comprobando otras ramas, la complejidad es más compleja más tarde que tener claras separaciones entre ramas. Además, si el archivo YAML se va a mantener durante mucho tiempo, debe tener disposiciones claras y hojas de ruta en diferentes ramas. La redundancia es inevitable, pero la intención de separar la lógica específica pagará más a largo plazo por la mantenibilidad.

Es por eso que también enfatizo las inclusiones y exclusiones de ramas en mi respuesta :)

Eriawan Kusumawardhono
fuente
Gracias por la sugerencia, pero mi canalización ya ha utilizado el disparador para diferentes propósitos también. (Para ser honesto, la característica de activación en sí misma se siente menos flexible, en comparación con Jenkins. Difícil de implementar las condiciones como cancelar la construcción duplicada de pr / rama, etc.) También habrá demasiadas líneas redundantes si tengo que hacerlo. repita los mismos trabajos nuevamente solo para cambiar un solo valor por rama. (También puedo solucionar el problema para repetir secciones de variables, lo que sería un código menos redundante.)
kevmando
Tal vez necesito pensar fuera de la caja de 'jenkins' ya que no es Jenkins, pero al equipo no le gusta tener una nueva tubería sin ventaja aparente.
kevmando
Nueva tubería? No. Eso es YAML en un archivo, por lo que se puede utilizar en una tubería que puede servir de muchas ramas,
Eriawan Kusumawardhono
Lo que quise decir como nueva tubería es que el nuevo flujo de trabajo funciona de manera diferente al flujo de trabajo anterior. No está relacionado con este tema, pero tiene más opciones de activación, ya que se mencionó aquí.
kevmando
OP no pregunta cómo activar una compilación basada en un valor de bifurcación. La pregunta que se hizo fue cómo hacer que un valor variable sea condicional en función del contexto en el que se activa la canalización. Su solución cuando se aplica a la pregunta real obliga a OP a crear 2 canales 1) trigger = master & env = a 2) trigger = dev & env = b.
Josh Gust el