Espressioni

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

Importante

Selezionare una versione dal selettore Della versione del contenuto di Azure DevOps.

Selezionare la versione di questo articolo corrispondente alla piattaforma e alla versione. Il selettore di versione è sopra il sommario. Cercare la piattaforma e la versione di Azure DevOps.

Le espressioni possono essere usate in molte posizioni in cui è necessario specificare un valore stringa, booleano o numerico durante la creazione di una pipeline. Quando un'espressione restituisce una matrice, si applicano le normali regole di indicizzazione e l'indice inizia con 0.

L'uso più comune delle espressioni è in condizioni per determinare se deve essere eseguito un processo o un passaggio.

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

Un altro uso comune delle espressioni consiste nella definizione delle variabili. Le espressioni possono essere valutate in fase di compilazione o in fase di esecuzione. Le espressioni in fase di compilazione possono essere usate ovunque; Le espressioni di runtime possono essere usate in variabili e condizioni. Le espressioni di runtime sono concepite come un modo per calcolare il contenuto delle variabili e dello stato (ad esempio: 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 differenza tra la sintassi delle espressioni in fase di compilazione e runtime è principalmente il contesto disponibile. In un'espressione in fase di compilazione (${{ <expression> }}) è possibile accedere a parameters e definire variablesstaticamente . In un'espressione di runtime ($[ <expression> ]) è possibile accedere a più variables parametri, ma non a parametri.

In questo esempio, un'espressione di runtime imposta il valore di $(isMain). Una variabile statica in un'espressione di compilazione imposta il valore di $(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

Un'espressione può essere un valore letterale, un riferimento a una variabile, un riferimento a una dipendenza, una funzione o una combinazione annidata valida di queste.

Valori letterali

Come parte di un'espressione, è possibile usare valori letterali booleani, null, number, string o version.

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

Booleano

True e False sono espressioni letterali booleane.

Null

Null è un'espressione letterale speciale restituita da un dizionario mancante, ad esempio (variables['noSuch']). Null può essere l'output di un'espressione, ma non può essere chiamato direttamente all'interno di un'espressione.

Numero

Inizia con '-', '.' o '0' fino a '9'.

String

Deve essere racchiuso tra virgolette singole. Ad esempio: 'this is a string'.

Per esprimere una virgoletta singola letterale, eseguire l'escape con una virgoletta singola. Ad esempio: 'It''s OK if they''re using contractions.'.

È possibile usare un carattere pipe (|) per le stringhe su più righe.

myKey: |
  one
  two
  three

Versione

Numero di versione con un massimo di quattro segmenti. Deve iniziare con un numero e contenere due o tre caratteri (.). Ad esempio: 1.2.3.4.

Variabili

Come parte di un'espressione, è possibile accedere alle variabili usando una delle due sintassi seguenti:

  • Sintassi dell'indice: variables['MyVar']
  • Sintassi di dereferenziazione delle proprietà: variables.MyVar

Per usare la sintassi di dereferenziazione delle proprietà, il nome della proprietà deve:

  • Iniziare con a-Z o _
  • Essere seguiti da a-Z0-9 o _

A seconda del contesto di esecuzione, sono disponibili variabili diverse.

Le variabili sono sempre stringhe. Se si vogliono usare valori tipizzati, è consigliabile usare i parametri.

Nota

Esiste una limitazione per l'uso di variabili con espressioni per le pipeline classiche e YAML durante la configurazione di tali variabili tramite l'interfaccia utente della scheda variabili. Le variabili definite come espressioni non devono dipendere da un'altra variabile con espressione in valore perché non è garantito che entrambe le espressioni vengano valutate correttamente. Ad esempio, si dispone di una variabile a il cui valore $[ <expression> ] viene usato come parte per il valore della variabile b. Poiché l'ordine delle variabili di elaborazione non è garantito b , potrebbe avere un valore non corretto della variabile a dopo la valutazione.

Le costruzioni descritte sono consentite solo durante la configurazione delle variabili tramite la parola chiave variables nella pipeline YAML. È necessario inserire le variabili nell'ordine in cui devono essere elaborate per ottenere i valori corretti dopo l'elaborazione.

Funzioni

Nelle espressioni è possibile usare le funzioni predefinite seguenti.

e

  • Restituisce True se tutti i parametri sono True
  • Parametri min: 2. Numero massimo di parametri: N
  • Esegue il cast dei parametri in booleano per la valutazione
  • Corto circuito dopo il primo False
  • Esempio: and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))

coalesce

  • Valuta i parametri in ordine (da sinistra a destra) e restituisce il primo valore che non è null o empty-string.
  • Non viene restituito alcun valore se i valori dei parametri sono tutte stringhe null o vuote.
  • Parametri min: 2. Numero massimo di parametri: N
  • Esempio: coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')

contains

  • Valuta se il True parametro left String contiene il parametro right
  • Parametri min: 2. Numero massimo di parametri: 2
  • Esegue il cast dei parametri in String per la valutazione
  • Esegue il confronto tra maiuscole e minuscole ordinali
  • Esempio: contains('ABCDE', 'BCD') (restituisce True)

containsValue

  • True Valuta se il parametro sinistro è una matrice e qualsiasi elemento è uguale al parametro destro. Valuta True anche se il parametro sinistro è un oggetto e il valore di qualsiasi proprietà è uguale al parametro destro.
  • Parametri min: 2. Numero massimo di parametri: 2
  • Se il parametro sinistro è una matrice, convertire ogni elemento in modo che corrisponda al tipo del parametro destro. Se il parametro sinistro è un oggetto, convertire il valore di ogni proprietà in modo che corrisponda al tipo del parametro destro. Il confronto di uguaglianza per ogni elemento specifico valuta False se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Corto circuito dopo la prima partita

Nota

Non esiste una sintassi letterale in una pipeline YAML per specificare una matrice. Questa funzione è di uso limitato nelle pipeline generali. È destinato all'uso nel contesto dell'elemento Decorator della pipeline con matrici fornite dal sistema, ad esempio l'elenco dei passaggi.

È possibile usare l'espressione containsValue per trovare un valore corrispondente in un oggetto . Di seguito è riportato un esempio che illustra la ricerca nell'elenco dei rami di origine per una corrispondenza per 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

  • Accettare un oggetto complesso e lo restituisce come JSON.
  • Parametri min: 1. Numero massimo di parametri: 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) }}

Output dello script:

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

counter

  • Questa funzione può essere usata solo in un'espressione che definisce una variabile. Non può essere usato come parte di una condizione per un passaggio, un processo o una fase.
  • Valuta un numero incrementato con ogni esecuzione di una pipeline.
  • Parametri: 2. prefix e seed.
  • Il prefisso è un'espressione stringa. Viene rilevato un valore separato del contatore per ogni valore univoco del prefisso. Deve prefix usare caratteri UTF-16.
  • Seed è il valore iniziale del contatore

È possibile creare un contatore incrementato automaticamente di uno in ogni esecuzione della pipeline. Quando si definisce un contatore, si specifica un prefix oggetto e un oggetto seed. Di seguito è riportato un esempio che illustra questa operazione.

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)

Il valore di minor nell'esempio precedente nella prima esecuzione della pipeline è 100. Nella seconda esecuzione è 101, purché il valore di major sia ancora 1.

Se si modifica il file YAML e si aggiorna il valore della variabile major su 2, nell'esecuzione successiva della pipeline il valore di minor sarà 100. Le esecuzioni successive incrementano il contatore a 101, 102, 103, ...

Successivamente, se si modifica il file YAML e si imposta il valore di major su 1, il valore del contatore riprende dove è rimasto per tale prefisso. In questo esempio riprende a 102.

Ecco un altro esempio di impostazione di una variabile da usare come contatore che inizia da 100, viene incrementato di 1 per ogni esecuzione e viene reimpostato su 100 ogni giorno.

Nota

pipeline.startTime non è disponibile all'esterno delle espressioni. pipeline.startTime formatta system.pipelineStartTime in un oggetto data e ora in modo che sia disponibile per lavorare con le espressioni. Il fuso orario predefinito per pipeline.startTime è UTC. È possibile modificare il fuso orario per l'organizzazione.

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

Di seguito è riportato un esempio di presenza di un contatore che mantiene un valore separato per le richieste pull e le esecuzioni ci.

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

I contatori hanno come ambito una pipeline. In altre parole, il valore viene incrementato per ogni esecuzione della pipeline. Non sono presenti contatori con ambito progetto.

endsWith

  • Valuta se il True parametro left String termina con il parametro right
  • Parametri min: 2. Numero massimo di parametri: 2
  • Esegue il cast dei parametri in String per la valutazione
  • Esegue il confronto tra maiuscole e minuscole ordinali
  • Esempio: endsWith('ABCDE', 'DE') (restituisce True)

eq

  • True Valuta se i parametri sono uguali
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Restituisce False se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: eq(variables.letters, 'ABC')

format

  • Valuta i parametri finali e li inserisce nella stringa del parametro iniziale
  • Parametri min: 1. Numero massimo di parametri: N
  • Esempio: format('Hello {0} {1}', 'John', 'Doe')
  • Usa identificatori di formato di data e ora personalizzati .NET per la formattazione della data (yyyy, yy, MMM, , dd, mffffdfffHHsssmmH) K
  • Esempio: format('{0:yyyyMMdd}', pipeline.startTime). In questo caso pipeline.startTime è una variabile di oggetto data/ora speciale.
  • Escape raddoppiando le parentesi graffe. Ad esempio: format('literal left brace {{ and literal right brace }}')

ge

  • True Valuta se il parametro left è maggiore o uguale al parametro destro
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Errori se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: ge(5, 5) (restituisce True)

gt

  • True Valuta se il parametro left è maggiore del parametro destro
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Errori se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: gt(5, 2) (restituisce True)

in

  • True Valuta se il parametro left è uguale a qualsiasi parametro destro
  • Parametri min: 1. Numero massimo di parametri: N
  • Converte i parametri di destra in modo che corrispondano al tipo di parametro sinistro. Il confronto di False uguaglianza valuta se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Corto circuito dopo la prima partita
  • Esempio: in('B', 'A', 'B', 'C') (restituisce True)

join

  • Concatena tutti gli elementi nella matrice di parametri destra, separati dalla stringa del parametro a sinistra.
  • Parametri min: 2. Numero massimo di parametri: 2
  • Ogni elemento della matrice viene convertito in una stringa. Gli oggetti complessi vengono convertiti in stringa vuota.
  • Se il parametro corretto non è una matrice, il risultato è il parametro corretto convertito in una stringa.

In questo esempio viene aggiunto un punto e virgola tra ogni elemento della matrice. Il tipo di parametro è un oggetto .

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

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

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

le

  • True Valuta se il parametro left è minore o uguale al parametro destro
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Errori se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: le(2, 2) (restituisce True)

length

  • Restituisce la lunghezza di una stringa o di una matrice, uno proveniente dal sistema o proveniente da un parametro
  • Parametri min: 1. Max parameters 1
  • Esempio: length('fabrikam') restituisce 8

lower

  • Converte un valore stringa o variabile in tutti i caratteri minuscoli
  • Parametri min: 1. Max parameters 1
  • Restituisce l'equivalente minuscolo di una stringa
  • Esempio: lower('FOO') restituisce foo

lt

  • True Valuta se il parametro left è minore del parametro destro
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Errori se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: lt(2, 5) (restituisce True)

ne

  • True Valuta se i parametri non sono uguali
  • Parametri min: 2. Numero massimo di parametri: 2
  • Converte il parametro right in modo che corrisponda al tipo di parametro sinistro. Restituisce True se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Esempio: ne(1, 2) (restituisce True)

not

  • True Valuta se il parametro èFalse
  • Parametri min: 1. Numero massimo di parametri: 1
  • Converte il valore in booleano per la valutazione
  • Esempio: not(eq(1, 2)) (restituisce True)

notIn

  • True Valuta se il parametro left non è uguale a qualsiasi parametro destro
  • Parametri min: 1. Numero massimo di parametri: N
  • Converte i parametri di destra in modo che corrispondano al tipo di parametro sinistro. Il confronto di False uguaglianza valuta se la conversione non riesce.
  • Confronto tra maiuscole e minuscole ordinali per stringhe
  • Corto circuito dopo la prima partita
  • Esempio: notIn('D', 'A', 'B', 'C') (restituisce True)

or

  • True Valuta se un parametro èTrue
  • Parametri min: 2. Numero massimo di parametri: N
  • Esegue il cast dei parametri in booleano per la valutazione
  • Corto circuito dopo il primo True
  • Esempio: or(eq(1, 1), eq(2, 3)) (restituisce True, cortocircuiti)

replace

  • Restituisce una nuova stringa in cui tutte le istanze di una stringa nell'istanza corrente vengono sostituite con un'altra stringa
  • Parametri min: 3. Numero massimo di parametri: 3
  • replace(a, b, c): restituisce un oggetto , con tutte le istanze di b sostituite da c
  • Esempio: replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server') (restituisce http://server/saml/consume)

split

  • Suddivide una stringa in sottostringhe in base ai caratteri di delimitazione specificati
  • Parametri min: 2. Numero massimo di parametri: 2
  • Il primo parametro è la stringa da dividere
  • Il secondo parametro è costituito dai caratteri delimitatori
  • Restituisce una matrice di sottostringhe. La matrice include stringhe vuote quando i caratteri di delimitazione vengono visualizzati consecutivamente o alla fine della stringa
  • Esempio:
    variables:
    - name: environments
      value: prod1,prod2 
    steps:  
      - ${{ each env in split(variables.environments, ',')}}:
        - script: ./deploy.sh --environment ${{ env }}
    
  • Esempio di uso di 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

  • True Valuta se la stringa del parametro left inizia con il parametro right
  • Parametri min: 2. Numero massimo di parametri: 2
  • Esegue il cast dei parametri in String per la valutazione
  • Esegue il confronto tra maiuscole e minuscole ordinali
  • Esempio: startsWith('ABCDE', 'AB') (restituisce True)

upper

  • Converte un valore stringa o variabile in tutti i caratteri maiuscoli
  • Parametri min: 1. Max parameters 1
  • Restituisce l'equivalente maiuscolo di una stringa
  • Esempio: upper('bah') restituisce BAH

xor

  • True Valuta se esattamente un parametro èTrue
  • Parametri min: 2. Numero massimo di parametri: 2
  • Esegue il cast dei parametri in booleano per la valutazione
  • Esempio: xor(True, False) (restituisce True)

Funzioni di controllo dello stato del processo

È possibile usare le funzioni di controllo dello stato seguenti come espressioni in condizioni, ma non nelle definizioni delle variabili.

sempre

  • Restituisce True sempre (anche quando viene annullato). Nota: un errore critico può comunque impedire l'esecuzione di un'attività. Ad esempio, se il recupero delle origini non è riuscito.

Annullato

  • Restituisce True se la pipeline è stata annullata.

failed

  • Per un passaggio, equivalente a eq(variables['Agent.JobStatus'], 'Failed').
  • Per un processo:
    • Senza argomenti, restituisce True solo se un processo precedente nel grafico delle dipendenze non è riuscito.
    • Con i nomi dei processi come argomenti, restituisce True solo se uno di questi processi non è riuscito.

succeeded

  • Per un passaggio, equivalente a in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
  • Usare con dependsOn quando si lavora con i processi e si vuole valutare se un processo precedente ha avuto esito positivo. I processi sono progettati per l'esecuzione in parallelo mentre le fasi vengono eseguite in sequenza.
  • Per un processo:
    • Senza argomenti, restituisce True solo se tutti i processi precedenti nel grafico delle dipendenze hanno avuto esito positivo o parziale.
    • Con i nomi dei processi come argomenti, restituisce True se tutti i processi hanno avuto esito positivo o parziale.
    • Restituisce False se la pipeline viene annullata.

succeededOrFailed

  • Per un passaggio, equivalente a in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed')

  • Per un processo:

    • Senza argomenti, restituisce True indipendentemente dal fatto che i processi nel grafico delle dipendenze abbiano avuto esito positivo o negativo.
    • Con i nomi dei processi come argomenti, restituisce True se uno di questi processi ha avuto esito positivo o negativo.
    • È possibile usare not(canceled()) invece quando sono presenti processi ignorati precedenti nel grafico delle dipendenze.

    Questo è simile always()a , ad eccezione del fatto che valuterà False quando la pipeline viene annullata.

Inserimento condizionale

È possibile usare ifle clausole , elseife else per assegnare in modo condizionale i valori delle variabili o impostare gli input per le attività. È anche possibile eseguire in modo condizionale un passaggio quando viene soddisfatta una condizione.

È possibile usare if per assegnare in modo condizionale i valori delle variabili o impostare gli input per le attività. È anche possibile eseguire in modo condizionale un passaggio quando viene soddisfatta una condizione.

Le elseif clausole e else sono disponibili a partire da Azure DevOps 2022 e non sono disponibili per Azure DevOps Server 2020 e versioni precedenti di Azure DevOps.

Le istruzioni condizionali funzionano solo quando si usa la sintassi del modello. Altre informazioni sulla sintassi delle variabili.

Per i modelli, è possibile usare l'inserimento condizionale quando si aggiunge una sequenza o un mapping. Altre informazioni sull'inserimento condizionale nei modelli.

Assegnare in modo condizionale una variabile

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}}

Impostare in modo condizionale un input dell'attività

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'

Eseguire in modo condizionale un passaggio

Se non è presente alcun set di variabili o il valore di foo non corrisponde alle if condizioni, l'istruzione else viene eseguita. In questo caso il valore di foo restituisce true nella elseif condizione.

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"

Parola chiave each

È possibile usare la each parola chiave per scorrere i parametri con il tipo di oggetto.

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

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

Inoltre, è possibile scorrere gli elementi annidati all'interno di un oggetto .

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 }}

Dipendenze

Le espressioni possono usare il contesto delle dipendenze per fare riferimento a processi o fasi precedenti. È possibile usare le dipendenze per:

  • Fare riferimento allo stato del processo di un processo precedente
  • Fare riferimento allo stato della fase di una fase precedente
  • Fare riferimento alle variabili di output nel processo precedente nella stessa fase
  • Fare riferimento alle variabili di output nella fase precedente in una fase
  • Fare riferimento alle variabili di output in un processo in una fase precedente nella fase seguente

Il contesto viene chiamato dependencies per processi e fasi e funziona in modo molto simile alle variabili. Se si fa riferimento a una variabile di output da un processo in un'altra fase, il contesto viene chiamato stageDependencies.

Se si verificano problemi con le variabili di output con caratteri virgolette (' o ") in essi, vedere questa guida alla risoluzione dei problemi.

Panoramica della sintassi delle dipendenze

La sintassi di riferimento alle variabili di output con le dipendenze varia a seconda delle circostanze. Ecco una panoramica degli scenari più comuni. Potrebbero verificarsi momenti in cui funziona anche la sintassi alternativa.

Type

Descrizione

stage to stage dependency (diverse fasi)

Fare riferimento a una variabile di output da una fase precedente in un processo in una fase diversa in una condizione in stages.

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

dipendenza da processo a processo (stessa fase)

Fare riferimento a una variabile di output in un processo diverso nella stessa fase in stages.

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

Fare riferimento a una variabile di output in una fase diversa in un oggetto job.

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

Fare riferimento alla variabile di output in un processo di distribuzione in una fase diversa in stages.

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

Fase per la gestione temporanea delle dipendenze (processo di distribuzione con risorsa)

Fare riferimento a una variabile di output in un processo di distribuzione che include una risorsa in una fase diversa in stages.

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

Esistono anche sintassi diverse per le variabili di output nei processi di distribuzione a seconda della strategia di distribuzione. Per altre informazioni, vedere Processi di distribuzione.

Fasi per la gestione temporanea delle dipendenze

Strutturalmente, l'oggetto dependencies è una mappa dei nomi di processo e di fase a results e outputs. Espresso come JSON, sarà simile al seguente:

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

Nota

Negli esempi seguenti viene usata la sintassi della pipeline standard. Se si usano pipeline di distribuzione, la sintassi delle variabili variabili e condizionali sarà diversa. Per informazioni sulla sintassi specifica da usare, vedere Processi di distribuzione.

Utilizzare questo formato di dependencies per eseguire il mapping in variabili o controllare le condizioni a livello di fase.

In questo esempio sono presenti due fasi, A e B. Fase A ha la condizione false e non verrà mai eseguita di conseguenza. La fase B viene eseguita se il risultato della fase A è Succeeded, SucceededWithIssueso Skipped. La fase B viene eseguita perché la fase A è stata ignorata.

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

Le fasi possono anche usare variabili di output da un'altra fase. In questo esempio sono presenti anche due fasi. La fase A include un processo, A1, che imposta una variabile shouldrun di output su true. La fase B viene eseguita quando shouldrun è true. Poiché shouldrun è true, viene eseguita 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

Per impostazione predefinita, ogni fase di una pipeline dipende da quella appena precedente nel file YAML. Se è necessario fare riferimento a una fase che non è immediatamente precedente a quella corrente, è possibile eseguire l'override di questa impostazione predefinita automatica aggiungendo una dependsOn sezione alla fase.

Dipendenze da processo a processo all'interno di una fase

A livello di processo all'interno di una singola fase, i dependencies dati non contengono informazioni a livello di fase.

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

In questo esempio sono presenti tre processi (a, b e c). Il processo verrà sempre ignorato a causa di condition: false. Il processo b viene eseguito perché non sono presenti condizioni associate. Il processo c viene eseguito perché tutte le relative dipendenze hanno esito positivo (processo b) o vengono ignorate (processo 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

In questo esempio il processo B dipende da una variabile di output del processo 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

Dipendenze da processo a fasi diverse

A livello di processo, è anche possibile fare riferimento agli output di un processo in una fase precedente. Ciò richiede l'uso del stageDependencies contesto.

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

In questo esempio, il processo B1 viene eseguito se il processo A1 viene ignorato. Il processo B2 controlla il valore della variabile di output del processo A1 per determinare se deve essere eseguito.

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

Se un processo dipende da una variabile definita da un processo di distribuzione in una fase diversa, la sintassi è diversa. Nell'esempio seguente il processo run_tests viene eseguito se il build_job processo di distribuzione è impostato su runTeststrue. Si noti che la chiave usata per il outputs dizionario è 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:
        ...

Variabili di output del processo di distribuzione

Se una fase dipende da una variabile definita da un processo di distribuzione in una fase diversa, la sintassi è diversa. Nell'esempio seguente la fase test dipende dall'impostazione shouldTest di distribuzione build_job su true. Si noti che nella fase conditiontest viene build_job visualizzato due volte.

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

Nell'esempio precedente la condizione fa riferimento a un ambiente e non a una risorsa di ambiente. Per fare riferimento a una risorsa di ambiente, è necessario aggiungere il nome della risorsa di ambiente alla condizione delle dipendenze. Nell'esempio seguente la condizione fa riferimento a una risorsa macchina virtuale dell'ambiente denominata 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

Matrici filtrate

Quando si opera su una raccolta di elementi, è possibile usare la * sintassi per applicare una matrice filtrata. Una matrice filtrata restituisce tutti gli oggetti/elementi indipendentemente dai nomi.

Si consideri ad esempio una matrice di oggetti denominati foo. Si vuole ottenere una matrice dei valori della id proprietà in ogni oggetto nella matrice.

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

È possibile eseguire le operazioni seguenti:

foo.*.id

In questo modo il sistema deve operare foo come matrice filtrata e quindi selezionare la id proprietà .

Verrà restituito quanto segue:

[ 1, 2, 3 ]

Cast dei tipi

I valori in un'espressione possono essere convertiti da un tipo a un altro durante la valutazione dell'espressione. Quando viene valutata un'espressione, i parametri vengono uniti al tipo di dati pertinente e quindi restituiti in stringhe.

In questo YAML, ad esempio, i valori True e False vengono convertiti in 1 e 0 quando l'espressione viene valutata. La funzione lt() restituisce True quando il parametro sinistro è minore del parametro destro.

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

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

In questo esempio, i valori variables.emptyString e la stringa vuota restituiscono entrambe stringhe vuote. La funzione coalesce() valuta i parametri in ordine e restituisce il primo valore che non è uguale a null o empty-string.

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

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

Le regole di conversione dettagliate sono elencate di seguito.

Da /A Booleano Null Numero String Versione
Booleano - - -
Null - -
Numero - - Parziale
Stringa Parziale Partial - Partial
Versione - - -

Booleano

A numero:

  • False0
  • True1

Per la stringa:

  • False'False'
  • True'True'

Null

  • A booleano: False
  • A numero: 0
  • Per stringa: '' (stringa vuota)

Numero

  • Per booleano: 0False, qualsiasi altro numero → True
  • Per la versione: deve essere maggiore di zero e deve contenere un decimale diverso da zero. Deve essere minore di Int32.MaxValue (componente decimale).
  • Per stringa: converte il numero in una stringa senza separatori di migliaia e senza separatore decimale.

String

  • Per booleano: '' (stringa vuota) → False, qualsiasi altra stringa → True
  • Per null: '' (stringa vuota) → Null, qualsiasi altra stringa non convertibile
  • A numero: '' (stringa vuota) → 0, in caso contrario, esegue C# Int32.TryParse usando InvariantCulture e le regole seguenti: AllowDecimalPoint | AllowLeadingSign | AllowLeadingWhite | AllowThousands | AllowTrailingWhite. Se TryParse ha esito negativo, non è convertibile.
  • Per la versione: esegue Version.TryParse. Deve contenere almeno il componente Principale e Secondario. Se TryParse ha esito negativo, non è convertibile.

Versione

  • A booleano: True
  • Per stringa: Major.Minor o Major.Minor.Build o Major.Minor.Build.Revision.

Domande frequenti

Si vuole eseguire un'operazione non supportata dalle espressioni. Quali opzioni sono disponibili per l'estensione della funzionalità pipeline?

È possibile personalizzare la pipeline con uno script che include un'espressione. Ad esempio, questo frammento accetta la BUILD_BUILDNUMBER variabile e la divide con Bash. Questo script restituisce due nuove variabili e $MAJOR_RUN$MINOR_RUN, per i numeri di esecuzione principali e secondari. Le due variabili vengono quindi usate per creare due variabili $major della pipeline e $minor con task.setvariable. Queste variabili sono disponibili per i passaggi downstream. Per condividere le variabili tra le pipeline, vedere Gruppi di variabili.

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)"