Expresiones

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

Importante

Seleccione una versión en el selector de versiones del contenido de Azure DevOps.

Seleccione la versión de este artículo que corresponde a su plataforma y versión. El selector de versiones está encima de la tabla de contenido. Busque la versión y la plataforma de Azure DevOps.

Las expresiones se pueden usar en muchos lugares donde es necesario especificar una cadena, un valor booleano o numérico al crear una canalización. Cuando una expresión devuelve una matriz, se aplican reglas de indexación normales y el índice comienza por 0.

El uso más común de expresiones es en condiciones para determinar si se debe ejecutar un trabajo o un paso.

# Expressions are used to define conditions for a step, job, or stage
steps:
- task: ...
  condition: <expression>

Otro uso común de expresiones consiste en definir variables. Las expresiones se pueden evaluar en tiempo de compilación o en tiempo de ejecución. Las expresiones de tiempo de compilación se pueden utilizar en cualquier lugar; las expresiones en tiempo de ejecución se pueden usar en variables y condiciones. Las expresiones en tiempo de ejecución están diseñadas como una manera de calcular el contenido de las variables y el estado (ejemplo: condition).

# Two examples of expressions used to define variables
# The first one, a, is evaluated when the YAML file is compiled into a plan.
# The second one, b, is evaluated at runtime.
# Note the syntax ${{}} for compile time and $[] for runtime expressions.
variables:
  a: ${{ <expression> }}
  b: $[ <expression> ]

La diferencia entre las sintaxis de expresiones en tiempo de ejecución y en tiempo de compilación es principalmente qué contexto está disponible. En una expresión en tiempo de compilación (${{ <expression> }}), tiene acceso a parameters y variables se define estáticamente. En una expresión en tiempo de ejecución ($[ <expression> ]), tiene acceso a más variables, pero no a los parámetros.

En este ejemplo, una expresión en tiempo de ejecución establece el valor de $(isMain). Una variable estática en una expresión de compilación establece el valor de $(compileVar).

variables:
  staticVar: 'my value' # static variable
  compileVar: ${{ variables.staticVar }} # compile time expression
  isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression

steps:
  - script: |
      echo ${{variables.staticVar}} # outputs my value
      echo $(compileVar) # outputs my value
      echo $(isMain) # outputs True

Una expresión puede ser un literal, una referencia a una variable, una referencia a una dependencia, una función o una combinación anidada válida de estas.

Literales

Como parte de una expresión, puede usar literales booleanos, null, números, cadenas o versiones.

# Examples
variables:
  someBoolean: ${{ true }} # case insensitive, so True or TRUE also works
  someNumber: ${{ -1.2 }}
  someString: ${{ 'a b c' }}
  someVersion: ${{ 1.2.3 }}

Boolean

True y False son expresiones literales booleanas.

Null

Null es una expresión literal especial que se devuelve de un error de diccionario, por ejemplo (variables['noSuch']). Null puede ser el resultado de una expresión, pero no se puede llamar directamente dentro de una expresión.

Number

Comienza por "-", "." o de "0" a "9".

String

Debe estar entre comillas simples. Por ejemplo: 'this is a string'.

Para expresar una comilla simple literal, añada un carácter de escape mediante una comilla simple. Por ejemplo: 'It''s OK if they''re using contractions.'.

Puede usar un carácter de canalización (|) para cadenas de varias líneas.

myKey: |
  one
  two
  three

Versión

Número de versión con hasta cuatro segmentos. Debe comenzar con un número y contener dos o tres caracteres de punto (.). Por ejemplo: 1.2.3.4.

variables

Como parte de una expresión, puede acceder a las variables mediante una de estas dos sintaxis:

  • Sintaxis de índice: variables['MyVar']
  • Sintaxis de desreferenciación de propiedades: variables.MyVar

Para usar la sintaxis de desreferencia de propiedad, el nombre de la propiedad debe cumplir los siguientes requisitos:

  • Comience con a-Z o _
  • Debe ir seguido de a-Z 0-9 o _

En función del contexto de ejecución, hay disponibles distintas variables.

Las variables siempre son cadenas. Si desea utilizar valores con tipo, debe usar parámetros en su lugar.

Nota:

Hay una limitación para usar variables con expresiones tanto para canalizaciones clásicas como de YAML cuando se configuran estas variables mediante la interfaz de usuario de pestaña de variables. Las variables definidas como expresiones no deben depender de otra variable con expresión en valor, ya que no se garantiza que ambas expresiones se evalúen correctamente. Por ejemplo, tenemos la variable a cuyo valor $[ <expression> ] se usa como parte del valor de la variable b. Como el orden de las variables de procesamiento no está garantizada, la variable b podría tener un valor incorrecto de variable a después de la evaluación.

Las construcciones descritas solo se permiten mientras se configuran variables mediante la palabra clave de variables en la canalización de YAML. Es necesario colocar las variables en el orden en el que se deben procesar para obtener los valores correctos después del procesamiento.

Functions

Las siguientes funciones integradas se pueden usar en expresiones.

y

  • Se evalúa como True si todos los parámetros son True
  • Parámetros mínimos: 2. Parámetros máximos: N
  • Convierte los parámetros en booleanos para la evaluación.
  • Se cortocircuita después del primer False.
  • Ejemplo: and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))

coalesce

  • Evalúa los parámetros por orden (de izquierda a derecha) y devuelve el primer valor que no es igual a null o cadena vacía.
  • No se devuelve ningún valor si los valores de parámetro todos son cadenas nulas o vacías.
  • Parámetros mínimos: 2. Parámetros máximos: N
  • Ejemplo: coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')

contains

  • Evalúa True si el parámetro izquierdo String contiene el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte los parámetros en cadena para su evaluación.
  • Realiza una comparación de mayúsculas y minúsculas ordinal.
  • Ejemplo: contains('ABCDE', 'BCD') (devuelve True)

containsValue

  • Evalúa True si el parámetro izquierdo es una matriz y cualquier elemento es igual al parámetro derecho. También se evalúa True si el parámetro izquierdo es un objeto y el valor de cualquier propiedad es igual al parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Si el parámetro izquierdo es una matriz, convierta cada elemento para que coincida con el tipo del parámetro derecho. Si el parámetro izquierdo es un objeto, convierta el valor de cada propiedad para que coincida con el tipo del parámetro derecho. La comparación de igualdad de cada elemento específico evalúa False si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Se cortocircuita después de la primera coincidencia.

Nota:

No hay ninguna sintaxis literal en una canalización de YAML para especificar una matriz. Esta función es de uso limitado en canalizaciones generales. Está pensado para su uso en el contexto del decorador de canalización con matrices proporcionadas por el sistema, como la lista de pasos.

Puede usar la expresión containsValue para buscar un valor coincidente en un objeto. A continuación, se muestra un ejemplo que muestra la búsqueda de una coincidencia en la lista de ramas de origen Build.SourceBranch.

parameters:
- name: branchOptions
  displayName: Source branch options
  type: object
  default:
    - refs/heads/main
    - refs/heads/test

jobs:
  - job: A1 
    steps:
    - ${{ each value in parameters.branchOptions }}:
      - script: echo ${{ value }}

  - job: B1 
    condition: ${{ containsValue(parameters.branchOptions, variables['Build.SourceBranch']) }}
    steps:
      - script: echo "Matching branch found"

convertToJson

  • Tome un objeto complejo y genere una salida como JSON.
  • Parámetros mínimos: 1. Parámetros máximos: 1.
parameters:
  - name: listOfValues
    type: object
    default:
      this_is:
        a_complex: object
        with:
          - one
          - two

steps:
- script: |
    echo "${MY_JSON}"
  env:
    MY_JSON: ${{ convertToJson(parameters.listOfValues) }}

Salida del script:

{
  "this_is": {
    "a_complex": "object",
    "with": [
      "one",
      "two"
    ]
  }
}

counter

  • Esta función solo se puede usar en una expresión que define una variable. No se puede usar como parte de una condición para un paso, trabajo o etapa.
  • Evalúa un número que se incrementa con cada ejecución de una canalización.
  • Parámetros: 2. prefix y seed.
  • El prefijo es una expresión de cadena. Se realiza un seguimiento de un valor independiente del contador para cada valor único del prefijo. prefix debe usar caracteres UTF-16.
  • El valor de inicialización es el valor de inicio del contador.

Puede crear un contador que se incremente automáticamente en uno en cada ejecución de la canalización. Al definir un contador, proporciona prefix y seed. Este es un ejemplo de código que muestra justo esto.

variables:
  major: 1
  # define minor as a counter with the prefix as variable major, and seed as 100.
  minor: $[counter(variables['major'], 100)]

steps:
- bash: echo $(minor)

El valor de minor en el ejemplo anterior en la primera ejecución de la canalización es 100. En la segunda ejecución es 101, siempre que el valor de major siga siendo 1.

Si edita el archivo de YAML y actualiza el valor de la variable major para que sea 2, entonces en la siguiente ejecución de la canalización, el valor de minor será de 100. Las ejecuciones posteriores incrementan el contador a 101, 102, 103,...

Más adelante, si edita el archivo de YAML y establece el valor de major de nuevo en 1, el valor del contador se reanuda donde se dejó para ese prefijo. En este ejemplo, se reanuda en 102.

Este es otro ejemplo de cómo establecer una variable para que actúe como un contador que comienza en 100, se incrementa en 1 para cada ejecución y se restablece a 100 todos los días.

Nota:

pipeline.startTime no está disponible fuera de las expresiones. pipeline.startTime da formato a system.pipelineStartTime como un objeto de fecha y hora para que esté disponible para funcionar con expresiones. La zona horaria predeterminada para pipeline.startTime es UTC. Puede cambiar la zona horaria de su organización.

jobs:
- job:
  variables:
    a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
  steps:
  - bash: echo $(a)

Este es un ejemplo de tener un contador que mantiene un valor independiente para las solicitudes de incorporación de cambios y las ejecuciones de CI.

variables:
  patch: $[counter(variables['build.reason'], 0)]

Los contadores se limitan a una canalización. En otras palabras, su valor se incrementa para cada ejecución de esa canalización. No hay contadores limitados a proyectos.

endsWith

  • Evalúa True si el parámetro izquierdo String termina con el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte los parámetros en cadena para su evaluación.
  • Realiza una comparación de mayúsculas y minúsculas ordinal.
  • Ejemplo: endsWith('ABCDE', 'DE') (devuelve True)

eq

  • Evalúa True si los parámetros son iguales.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Devuelve False si se produce un error de conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: eq(variables.letters, 'ABC')

format

  • Evalúa los parámetros finales y los inserta en la cadena de parámetro inicial.
  • Parámetros mínimos: 1. Parámetros máximos: N
  • Ejemplo: format('Hello {0} {1}', 'John', 'Doe')
  • Usa especificadores de formato de fecha y hora personalizados de .NET para el formato de fecha (yyyy, yy, MM, M, dd, d, HH, H, m, mm, ss, s, f, ff, ffff, K).
  • Ejemplo: format('{0:yyyyMMdd}', pipeline.startTime). En este caso, pipeline.startTime es una variable de objeto de fecha y hora especial.
  • Añada un carácter de escape duplicando las llaves. Por ejemplo: format('literal left brace {{ and literal right brace }}')

ge

  • Evalúa True si el parámetro izquierdo es mayor o igual que el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Errores si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: ge(5, 5) (devuelve True)

gt

  • Evalúa True si el parámetro izquierdo es mayor que el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Errores si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: gt(5, 2) (devuelve True)

in

  • Evalúa True si el parámetro izquierdo es igual que el parámetro derecho.
  • Parámetros mínimos: 1. Parámetros máximos: N
  • Convierte los parámetros derechos para que coincidan con el tipo de parámetro izquierdo. La comparación de igualdad evalúa False si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Se cortocircuita después de la primera coincidencia.
  • Ejemplo: in('B', 'A', 'B', 'C') (devuelve True)

join

  • Concatena todos los elementos de la matriz del parámetro derecho, separados por la cadena del parámetro izquierdo.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Cada elemento de la matriz se convierte en una cadena. Los objetos complejos se convierten en una cadena vacía.
  • Si el parámetro derecho no es una matriz, el resultado es el parámetro derecho convertido en una cadena.

En este ejemplo, se agrega un punto y coma entre cada elemento de la matriz. El tipo del parámetro es un objeto.

parameters:
- name: myArray
  type: object
  default:
    - FOO
    - BAR
    - ZOO

variables:
   A: ${{ join(';',parameters.myArray) }}

steps:
  - script: echo $A # outputs FOO;BAR;ZOO

le

  • Evalúa True si el parámetro izquierdo es menor o igual que el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Errores si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: le(2, 2) (devuelve True)

length

  • Devuelve la longitud de una cadena o una matriz, ya sea una que provenga del sistema o que proceda de un parámetro.
  • Parámetros mínimos: 1. Parámetros máximos: 1
  • Ejemplo: length('fabrikam') devuelve 8

lower

  • Convierte un valor de cadena o variable a caracteres todos en minúsculas.
  • Parámetros mínimos: 1. Parámetros máximos: 1
  • Devuelve el equivalente en minúsculas de una cadena.
  • Ejemplo: lower('FOO') devuelve foo

lt

  • Evalúa True si el parámetro izquierdo es menor que el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Errores si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: lt(2, 5) (devuelve True)

ne

  • Evalúa True si los parámetros no son iguales.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte el parámetro derecho para que coincida con el tipo de parámetro izquierdo. Devuelve True si se produce un error de conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Ejemplo: ne(1, 2) (devuelve True)

not

  • Evalúa True si el parámetro es False.
  • Parámetros mínimos: 1. Parámetros máximos: 1
  • Convierte el valor en booleano para la evaluación.
  • Ejemplo: not(eq(1, 2)) (devuelve True)

notIn

  • Se evalúa como True si el parámetro izquierdo no es igual a ningún parámetro derecho
  • Parámetros mínimos: 1. Parámetros máximos: N
  • Convierte los parámetros derechos para que coincidan con el tipo de parámetro izquierdo. La comparación de igualdad evalúa False si se produce un error en la conversión.
  • Comparación de mayúsculas y minúsculas ordinal para cadenas
  • Se cortocircuita después de la primera coincidencia.
  • Ejemplo: notIn('D', 'A', 'B', 'C') (devuelve True)

o

  • Evalúa True si algún parámetro es True.
  • Parámetros mínimos: 2. Parámetros máximos: N
  • Convierte los parámetros en booleanos para la evaluación.
  • Se cortocircuita después del primer True.
  • Ejemplo: or(eq(1, 1), eq(2, 3)) (devuelve True, se cortocircuita)

replace

  • Devuelve una nueva cadena en la que todas las instancias de una cadena en la instancia actual se reemplazan por otra cadena.
  • Parámetros mínimos: 3. Parámetros máximos: 3
  • replace(a, b, c): devuelve a, con todas las instancias de b reemplazadas por c.
  • Ejemplo: replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server') (devuelve http://server/saml/consume)

split

  • Divide una cadena en subcadenas en función de los caracteres de delimitación especificados.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • El primer parámetro es la cadena que se va a dividir.
  • El segundo parámetro son los caracteres delimitadores.
  • Devuelve una matriz de subcadenas. La matriz incluye cadenas vacías cuando los caracteres delimitadores aparecen consecutivamente o al final de la cadena.
  • Ejemplo:
    variables:
    - name: environments
      value: prod1,prod2 
    steps:  
      - ${{ each env in split(variables.environments, ',')}}:
        - script: ./deploy.sh --environment ${{ env }}
    
  • Ejemplo de uso de split() con replace():
    parameters:
    - name: resourceIds
      type: object
      default:
      - /subscriptions/mysubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/loadBalancers/kubernetes-internal
      - /subscriptions/mysubscription02/resourceGroups/myResourceGroup02/providers/Microsoft.Network/loadBalancers/kubernetes
    - name: environments
      type: object
      default: 
      - prod1
      - prod2
    
    trigger:
    - main
    
    steps:
    - ${{ each env in parameters.environments }}:
      - ${{ each resourceId in parameters.resourceIds }}:
          - script: echo ${{ replace(split(resourceId, '/')[8], '-', '_') }}_${{ env }}
    

startsWith

  • Evalúa True si la cadena de parámetro izquierdo comienza con el parámetro derecho.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte los parámetros en cadena para su evaluación.
  • Realiza una comparación de mayúsculas y minúsculas ordinal.
  • Ejemplo: startsWith('ABCDE', 'AB') (devuelve True)

upper

  • Convierte un valor de cadena o variable a caracteres todos en mayúsculas.
  • Parámetros mínimos: 1. Parámetros máximos: 1
  • Devuelve el equivalente en mayúsculas de una cadena.
  • Ejemplo: upper('bah') devuelve BAH

xor

  • Evalúa True si un parámetro es exactamente True.
  • Parámetros mínimos: 2. Parámetros máximos: 2
  • Convierte los parámetros en booleanos para la evaluación.
  • Ejemplo: xor(True, False) (devuelve True)

Funciones de comprobación del estado del trabajo

Puede utilizar las siguientes funciones de comprobación de estado como expresiones en condiciones, pero no en definiciones de variables.

Siempre

  • Se evalúa siempre como True (incluso cuando se cancela). Nota: Un error crítico puede impedir que se ejecute una tarea. Por ejemplo, si fallaron las fuentes.

cancelado

  • Se evalúa como True si se ha cancelado la canalización.

con errores

  • Para un paso, es equivalente a eq(variables['Agent.JobStatus'], 'Failed').
  • Para un trabajo:
    • Sin argumentos, se evalúa como True solo si se ha producido un error en cualquier trabajo anterior en el gráfico de dependencias.
    • Con nombres de trabajo como argumentos, se evalúa como True solo si se ha producido un error en alguno de esos trabajos.

succeeded

  • Para un paso, es equivalente a in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
  • Úselo con dependsOn al trabajar con trabajos y cuando desee evaluar si un trabajo anterior se ha realizado correctamente. Los trabajos están diseñados para ejecutarse en paralelo, mientras que las fases se ejecutan de forma secuencial.
  • Para un trabajo:
    • Sin argumentos, evalúa True solo si todos los trabajos anteriores del gráfico de dependencias se han realizado de forma correcta total o parcialmente.
    • Con los nombres de trabajo como argumentos, se evalúa como True si todos estos trabajos se han realizado de forma correcta total o parcialmente.
    • Se evalúa como False si se cancela la canalización.

succeededOrFailed

  • Para un paso, es equivalente a in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed')

  • Para un trabajo:

    • Sin argumentos, se evalúa como True independientemente de si algún trabajo del gráfico de dependencias se ha realizado correctamente o no.
    • Con los nombres de trabajo como argumentos, se evalúa como True tanto si alguno de estos trabajos se ha realizado correctamente como si no.
    • Es posible que quiera usar not(canceled()) en su lugar cuando haya trabajos omitidos anteriores en el gráfico de dependencias.

    Esto es como always(), salvo que se evaluará False cuando se cancele la canalización.

Inserción condicional

Puede usar las cláusulas if, elseify else para asignar condicionalmente valores de variable o establecer entradas para las tareas. También puede ejecutar de forma condicional un paso cuando se cumple una condición.

Puede usar if para asignar condicionalmente valores de variable o establecer entradas para tareas. También puede ejecutar de forma condicional un paso cuando se cumple una condición.

Las cláusulas elseif y else están disponibles a partir de Azure DevOps 2022 y no están disponibles para Azure DevOps Server 2020 y versiones anteriores de Azure DevOps.

Los condicionales solo funcionan cuando se usa la sintaxis de plantillas. Más información sobre la sintaxis de variables.

En el caso de las plantillas, puede usar la inserción condicional al agregar una secuencia o una asignación. Más información sobre la inserción condicional en plantillas.

Asignación condicional de una variable

variables:
  ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: # only works if you have a main branch
    stageName: prod

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo ${{variables.stageName}}

Establecimiento condicional de una entrada de tarea

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(Pipeline.Workspace)'
    ${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
      artifact: 'prod'
    ${{ else }}:
      artifact: 'dev'
    publishLocation: 'pipeline'

Ejecución condicional de un paso

Si no hay ninguna variable establecida o si el valor de foo no coincide con las condiciones if, se ejecuta la instrucción else. Aquí el valor de foo devuelve true en la condición elseif.

variables:
  - name: foo
    value: contoso # triggers elseif condition

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo "start"
- ${{ if eq(variables.foo, 'adaptum') }}:
  - script: echo "this is adaptum"
- ${{ elseif eq(variables.foo, 'contoso') }}: # true
  - script: echo "this is contoso" 
- ${{ else }}:
  - script: echo "the value is not adaptum or contoso"

Each (palabra clave)

Puede usar la palabra clave each para recorrer los parámetros con el tipo de objeto.

parameters:
- name: listOfStrings
  type: object
  default:
  - one
  - two

steps:
- ${{ each value in parameters.listOfStrings }}:
  - script: echo ${{ value }}

Además, puede recorrer en iteración los elementos anidados dentro de un objeto.

parameters:
- name: listOfFruits
  type: object
  default:
  - fruitName: 'apple'
    colors: ['red','green']
  - fruitName: 'lemon'
    colors: ['yellow']
steps:
- ${{ each fruit in parameters.listOfFruits }} :
  - ${{ each fruitColor in fruit.colors}} :
    - script: echo ${{ fruit.fruitName}} ${{ fruitColor }}

Dependencias

Las expresiones pueden usar el contexto de dependencias para hacer referencia a fases o trabajos anteriores. Puede usar dependencias para:

  • Hacer referencia al estado del trabajo de un trabajo anterior.
  • Hacer referencia al estado de la fase de una fase anterior.
  • Hacer referencia a variables de salida del trabajo anterior en la misma fase.
  • Hacer referencia a variables de salida de la fase anterior en una fase.
  • Hacer referencia a variables de salida en un trabajo de una fase anterior en la siguiente fase.

El contexto se llama dependencies para los trabajos y fases y funciona de forma muy similar a las variables. Si hace referencia a una variable de salida de un trabajo en otra fase, el contexto se llama stageDependencies.

Si tiene problemas con las variables de salida que tienen caracteres de comillas (' o ") en ellas, consulte esta guía de solución de problemas.

Introducción a la sintaxis de dependencia

La sintaxis de hacer referencia a variables de salida con dependencias varía en función de las circunstancias. Esta es una introducción a los escenarios más comunes. Puede haber ocasiones en las que la sintaxis alternativa también funcione.

Tipo

Descripción

dependencia de fase a fase (diferentes fases)

Hacer referencia a una variable de salida de una fase anterior de un trabajo en una fase diferente en una condición de stages.

  • Sintaxis: and(succeeded(), eq(stageDependencies.<stage-name>.outputs['<job-name>.<step-name>.<variable-name>'], 'true'))
  • Ejemplo: and(succeeded(), eq(stageDependencies.A.outputs['A1.printvar.shouldrun'], 'true'))

Hacer referencia a una variable de salida en un trabajo diferente en la mismauna fase de stages.

  • Sintaxis: and(succeeded(), eq(dependencies.<job-name>.outputs['<step-name>.<variable-name>'], 'true'))
  • Ejemplo: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))

dependencia de trabajo a fase (diferentes fases)

Hacer referencia a una variable de salida en una fase diferente de job.

  • Sintaxis: eq(stageDependencies.<stage-name>.<job-name>.outputs['<step-name>.<variable-name>'], 'true')
  • Ejemplo: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')

dependencia de fase a fase (trabajo de implementación)

Hacer referencia a una variable de salida en un trabajo de implementación en una fase diferente de stages.

  • Sintaxis: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<deployment-job-name>.<step-name>.<variable-name>'], 'true')
  • Ejemplo: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')

dependencia de fase a fase (trabajo de implementación con recurso)

Hacer referencia a una variable de salida en un trabajo de implementación que incluya un recurso en una fase diferente de stages.

  • Sintaxis: eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<Deploy_resource-name>.<step-name>.<variable-name>'], 'true')
  • Ejemplo: eq(dependencies.build.outputs['build_job.Deploy_winVM.setRunTests.runTests'], 'true')

También hay diferentes sintaxis para las variables de salida en los trabajos de implementación en función de la estrategia de implementación. Para obtener más información, consulte Trabajos de implementación.

Dependencias de fase a fase

Estructuralmente, el objeto dependencies es una asignación de nombres de trabajos y fases a results y outputs. Expresado como JSON, tendría el siguiente aspecto:

"dependencies": {
  "<STAGE_NAME>" : {
    "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
    "outputs": {
        "jobName.stepName.variableName": "value"
    }
  },
  "...": {
    // another stage
  }
}

Nota:

En los ejemplos siguientes se usa la sintaxis de canalización estándar. Si utiliza canalizaciones de implementación, la sintaxis de variables y variables condicionales será distinta. Para obtener información sobre la sintaxis específica que se va a usar, consulte Trabajos de implementación.

Use esta forma de dependencies para asignarlo en variables o comprobar condiciones en un nivel de fase.

En este ejemplo, hay dos fases, A y B. La fase A tiene la condición false y no se ejecutará nunca como resultado. La fase B se ejecuta si el resultado de la fase A es Succeeded, SucceededWithIssueso Skipped. La etapa B se ejecuta porque se omitió la etapa A.

stages:
- stage: A
  condition: false
  jobs:
  - job: A1
    steps:
    - script: echo Job A1
- stage: B
  condition: in(dependencies.A.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
  jobs:
  - job: B1
    steps:
    - script: echo Job B1

Las fases también pueden usar variables de salida de otra fase. En este ejemplo, también hay dos fases. La fase A incluye un trabajo, A1, que establece una variable de salida en shouldrun a true. La fase B se ejecuta cuando shouldrun es true. Dado que shouldrun es true, se ejecuta la fase B.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
  dependsOn: A
  jobs:
  - job: B1
    steps:
    - script: echo hello from Stage B

Nota:

De forma predeterminada, cada fase de una canalización depende de la anterior en el archivo de YAML. Si necesita hacer referencia a una fase que no es inmediatamente anterior a la actual, puede invalidar este valor predeterminado automático agregando una sección dependsOn a la fase.

Dependencias de trabajo a trabajo dentro de una fase

En el nivel de trabajo de una sola fase, los datos dependencies no contienen información de nivel de fase.

"dependencies": {
  "<JOB_NAME>": {
    "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
    "outputs": {
      "stepName.variableName": "value1"
    }
  },
  "...": {
    // another job
  }
}

En este ejemplo, hay tres trabajos (a, b y c). El trabajo a siempre se omitirá debido a condition: false. El trabajo b se ejecuta porque no hay condiciones asociadas. El trabajo c se ejecuta porque todas sus dependencias son correctas (trabajo b) o se omiten (trabajo a).

jobs:
- job: a
  condition: false
  steps:
  - script: echo Job a
- job: b
  steps:
  - script: echo Job b
- job: c
  dependsOn:
  - a
  - b
  condition: |
    and
    (
      in(dependencies.a.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
      in(dependencies.b.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
    )
  steps:
  - script: echo Job c

En este ejemplo, el trabajo B depende de una variable de salida del trabajo A.

jobs:
- job: A
  steps:
  - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
  # or on Windows:
  # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
    name: printvar

- job: B
  condition: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))
  dependsOn: A
  steps:
  - script: echo hello from B

Dependencias de trabajo a trabajo entre fases

En el nivel de trabajo, también puede hacer referencia a salidas de un trabajo en una fase anterior. Esto requiere el uso del contexto stageDependencies.

"stageDependencies": {
  "<STAGE_NAME>" : {
    "<JOB_NAME>": {
      "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
      "outputs": {
          "stepName.variableName": "value"
      }
    },
    "...": {
      // another job
    }
  },
  "...": {
    // another stage
  }
}

En este ejemplo, el trabajo B1 se ejecuta si se omite el trabajo A1. El trabajo B2 comprueba el valor de la variable de salida del trabajo A1 para determinar si debe ejecutarse.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  dependsOn: A
  jobs:
  - job: B1
    condition: in(stageDependencies.A.A1.result, 'Skipped') # change condition to `Succeeded and stage will be skipped`
    steps:
    - script: echo hello from Job B1
  - job: B2
    condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
    steps:
     - script: echo hello from Job B2

Si un trabajo depende de una variable definida por un trabajo de implementación en una fase diferente, la sintaxis será diferente. En el ejemplo siguiente, el trabajo run_tests se ejecuta si el trabajo de implementación build_job establece runTests en true. Observe que la clave usada para el diccionario outputs es build_job.setRunTests.runTests.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: Production
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  jobs:  
    - job: run_tests
      condition: eq(stageDependencies.build.build_job.outputs['build_job.setRunTests.runTests'], 'true')
      steps:
        ...

Variables de salida del trabajo de implementación

Si una fase depende de una variable definida por un trabajo de implementación en una fase distinta, la sintaxis es diferente. En el ejemplo siguiente, la fase test depende de la implementación build_job que establece shouldTest en true. Observe que en condition de la fase test, build_job aparece dos veces.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: Production
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  condition: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')
  jobs:
    - job: A
      steps:
        - script: echo Hello from job A

En el ejemplo anterior, la condición hace referencia a un entorno y no a un recurso de entorno. Para hacer referencia a un recurso de entorno, deberá agregar el nombre del recurso de entorno a la condición de dependencias. En el ejemplo siguiente, la condición hace referencia a un recurso de máquina virtual de entorno denominado vmtest.

stages:
- stage: build
  jobs:
  - deployment: build_job
    environment:
      name: vmtest
      resourceName: winVM2
      resourceType: VirtualMachine
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            name: setRunTests
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $runTests = "true"
                echo "setting runTests: $runTests"
                echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"

- stage: test
  dependsOn:
  - 'build'
  condition: eq(dependencies.build.outputs['build_job.Deploy_winVM2.setRunTests.runTests'], 'true')
  jobs:
  - job: A
    steps:
     - script: echo Hello from job A

Matrices filtradas

Al trabajar en una colección de elementos, puede usar la sintaxis * para aplicar una matriz filtrada. Una matriz filtrada devuelve todos los objetos o elementos independientemente de sus nombres.

Como ejemplo, considere una matriz de objetos denominada foo. Queremos obtener una matriz de los valores de la propiedad id en cada objeto de nuestra matriz.

[
    { "id": 1, "a": "avalue1"},
    { "id": 2, "a": "avalue2"},
    { "id": 3, "a": "avalue3"}
]

Podríamos hacer lo siguiente:

foo.*.id

Esto indica al sistema que funcione en foo como una matriz filtrada y, a continuación, seleccione la propiedad id.

Esto devolvería:

[ 1, 2, 3 ]

Conversión de tipos

Los valores de una expresión se pueden convertir de un tipo a otro a medida que se evalúa la expresión. Cuando se evalúa una expresión, los parámetros se fusionan con el tipo de datos pertinente y, después, se vuelven a convertir en cadenas.

Por ejemplo, en este YAML, los valores True y False se convierten en 1 y 0 cuando se evalúa la expresión. La función lt() devuelve True cuando el parámetro izquierdo es menor que el parámetro derecho.

variables:
  firstEval: $[lt(False, True)] # 0 vs. 1, True
  secondEval: $[lt(True, False)] # 1 vs. 0, False

steps:
- script: echo $(firstEval)
- script: echo $(secondEval)

En este ejemplo, los valores variables.emptyString y la cadena vacía se evalúan como cadenas vacías. La función coalesce() evalúa los parámetros por orden y devuelve el primer valor que no es igual a null o cadena vacía.

variables:
  coalesceLiteral: $[coalesce(variables.emptyString, '', 'literal value')]

steps:
- script: echo $(coalesceLiteral) # outputs literal value

A continuación se enumeran las reglas de conversión detalladas.

De/A Boolean Null Number String Versión
Boolean - - -
Null - -
Number - - Parcial
String Parcial Parcial - Parcial
Versión - - -

Boolean

A número:

  • False0
  • True1

A cadena:

  • False'False'
  • True'True'

Null

  • A booleano: False
  • A número: 0
  • A cadena: '' (la cadena vacía)

Número

  • A booleano: 0False, cualquier otro número → True
  • A versión: debe ser mayor que cero y debe contener un decimal distinto de cero. Debe ser menor que Int32.MaxValue (también componente decimal).
  • A cadena: convierte el número a una cadena sin separador de miles ni ningún separador decimal.

String

  • A booleano: '' (la cadena vacía) → False, cualquier otra cadena → True
  • A null: '' (la cadena vacía) → Null, cualquier otra cadena no convertible
  • A número: '' (la cadena vacía) → 0; de lo contrario, ejecuta Int32.TryParse de C# mediante InvariantCulture y las reglas siguientes: AllowDecimalPoint | AllowLeadingSign | AllowLeadingWhite | AllowThousands | AllowTrailingWhite. Si se produce un error en TryParse, no es convertible.
  • A versión: ejecuta el archivo de C# Version.TryParse. Debe contener el componente Major y Minor como mínimo. Si se produce un error en TryParse, no es convertible.

Versión

  • A booleano: True
  • A cadena: Major.Minor o Major.Minor.Build o Major.Minor.Build.Revision.

Preguntas más frecuentes

Quiero hacer algo que no esté respaldado por expresiones. ¿Qué opciones tengo para extender la funcionalidad de Pipelines?

Puede personalizar la canalización con un script que incluya una expresión. Por ejemplo, este fragmento de código toma la variable BUILD_BUILDNUMBER y la divide con Bash. Este script genera dos nuevas variables, $MAJOR_RUN y $MINOR_RUN, para los números de ejecución Major y Minor. A continuación, las dos variables se usan para crear dos variables de canalización $major y $minor con task.setvariable. Estas variables están disponibles para los pasos descendentes. Para compartir variables entre canalizaciones, consulte Grupos de variables.

steps:
- bash: |
    MAJOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f1)
    echo "This is the major run number: $MAJOR_RUN"
    echo "##vso[task.setvariable variable=major]$MAJOR_RUN"

    MINOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
    echo "This is the minor run number: $MINOR_RUN"
    echo "##vso[task.setvariable variable=minor]$MINOR_RUN"

- bash: echo "My pipeline variable for major run is $(major)"
- bash: echo "My pipeline variable for minor run is $(minor)"