Condividi tramite


Condizioni della pipeline

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020

Questo articolo descrive le diverse condizioni che consentono l'esecuzione di una fase, un processo o un passaggio di Azure Pipelines e come impostare tali condizioni in una definizione di pipeline YAML.

Nota

Questo articolo illustra le funzionalità della pipeline YAML. Per le pipeline classiche, è possibile specificare alcune condizioni in cui le attività o i processi vengono eseguiti nelle opzioni di controllo di ogni attività e nelle opzioni Aggiuntive per un processo in una pipeline di versione.

Condizioni di esecuzione di una fase, di un processo o di un passaggio in

Per impostazione predefinita, un processo o una fase della pipeline viene eseguito se non dipende da altri processi o fasi o se tutte le relative dipendenze sono completate e riuscite. Il requisito di dipendenza si applica alle dipendenze dirette e alle relative dipendenze indirette, calcolate in modo ricorsivo.

Per impostazione predefinita, un passaggio viene eseguito se nulla nel suo processo è ancora fallito e il passaggio immediatamente precedente è completato. Per altre informazioni di contesto su fasi, processi e passaggi, vedere Concetti chiave per Azure Pipelines.

È possibile eseguire l'override o personalizzare questi comportamenti predefiniti impostando una fase, un processo o un passaggio da eseguire anche se o solo se una dipendenza precedente ha esito negativo o ha un altro risultato. È anche possibile definire condizioni personalizzate. In una definizione di pipeline YAML si usa la condition proprietà per specificare le condizioni in cui è possibile eseguire una fase, un processo o un passaggio.

Nota

Le condizioni si applicano a tutte le dipendenze dirette e indirette precedenti con lo stesso pool di agenti. Fasi o processi in pool di agenti diversi vengono eseguiti simultaneamente.

Le condizioni in base allo stato precedente delle dipendenze includono:

  • Operazione completata: viene eseguita solo se tutte le dipendenze precedenti hanno esito positivo. Questo comportamento è l'impostazione predefinita se non viene impostata alcuna condizione in YAML. Per applicare questa condizione, specificare condition: succeeded().
  • Operazione riuscita o non riuscita: eseguire anche se una dipendenza precedente non riesce, a meno che l'esecuzione non venga annullata. Per applicare questa condizione, specificare condition: succeededOrFailed().
  • Sempre: eseguire anche se una dipendenza precedente ha esito negativo, anche se l'esecuzione viene annullata. Per applicare questa condizione, specificare condition: always().
  • Non riuscito: viene eseguito solo quando una dipendenza precedente ha esito negativo. Per applicare questa condizione, specificare condition: failed().

Importante

Quando si specifica una proprietà per una condition fase, un processo o un passaggio, si sovrascrive la condizione predefinita. La fase, il processo o il passaggio potrebbero essere eseguiti anche se la compilazione viene annullata. Assicurarsi che le condizioni tengano conto dello stato della fase padre o del processo.

Esempio di condizione

Nell'esempio YAML seguente vengono illustrate le always() condizioni e failed() . La prima attività script nel processo 1 presenta una always condizione, quindi viene eseguita anche se le dipendenze hanno esito negativo o la compilazione viene annullata. Nella seconda attività di script exit job1, job1 costringe il processo a fallire.

Le fasi della pipeline vengono eseguite in sequenza per impostazione predefinita, ma i processi possono essere eseguiti in parallelo. È possibile usare la dependsOn proprietà per definire in modo esplicito le dipendenze tra fasi o processi.

Per impostare le condizioni per un processo che dipende dal risultato di un altro processo, usare dependsOn per definire la dipendenza. Nell'esempio seguente, job2 dipende da job1 e viene eseguito perché job1 ha esito negativo.

jobs:
- job: job1
  steps:
  - script: echo Hello!
    condition: always() # this step runs even if the build is canceled
  - script: |
      echo "This task will fail."
      exit job1 
- job: job2
  dependsOn: job1
  condition: failed() # this job runs only if job1 fails

Nota

È anche possibile usare l'interfaccia utente di Azure Pipelines per eseguire manualmente le fasi dipendenti quando la fase padre ha esito negativo. Per altre informazioni, vedere Eseguire le fasi figlio quando la fase padre ha esito negativo.

Condizioni personalizzate

Se le condizioni predefinite non soddisfano le proprie esigenze, è possibile specificare condizioni personalizzate come espressioni nelle definizioni di pipeline YAML.

L'agente valuta l'espressione che inizia con la funzione più interna e procede verso l'esterno. Il risultato finale è un valore booleano che determina se eseguire o meno la fase, il processo o il passaggio. Per una guida completa alla sintassi, vedere Espressioni.

Importante

Le condizioni vengono valutate per determinare se avviare una fase, un processo o un passaggio. Pertanto, non è possibile calcolare nulla durante il runtime di una fase, di un processo o di un passaggio per l'uso all'interno della stessa fase, processo o passaggio. Ad esempio, se si imposta una variabile in un processo usando un'espressione di runtime con $[ ] sintassi, non è possibile usare tale variabile in condizioni all'interno di tale processo.

Variabili in condizioni

È possibile impostare le variabili della pipeline e usarle in condizioni. La pipeline seguente imposta una isMain variabile e la usa in una condizione che esegue la fase B solo quando il ramo di origine della compilazione è main.

variables:
  isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]

stages:
- stage: A
  jobs:
  - job: A1
    steps:
      - script: echo Hello Stage A!
- stage: B
  condition: and(succeeded(), eq(variables.isMain, true))
  jobs:
  - job: B1
    steps:
      - script: echo Hello Stage B!
      - script: echo $(isMain)

È possibile impostare una condizione da eseguire se una variabile è null o una stringa vuota. Tutte le variabili vengono considerate come stringhe in Azure Pipelines, quindi una stringa vuota equivale a null nella pipeline seguente:

variables:
- name: testEmpty
  value: ''

jobs:
  - job: A
    steps:
    - script: echo testEmpty is blank
    condition: eq(variables.testEmpty, '')

Variabili di output del processo usate in altre condizioni del processo

È possibile creare una variabile in un processo che altri processi nella stessa fase possono specificare in condizioni. Le variabili disponibili per i processi dipendenti devono essere contrassegnate come variabili di output multi-processo usando isOutput=true, come nel codice seguente:

jobs:
- job: A
  steps:
  - bash: |
      echo "This is job A."
      echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
    name: DetermineResult
- job: B
  dependsOn: A
  condition: eq(dependencies.A.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
  steps:
  - script: echo "Job A ran and doThing is Yes."

Variabili di passaggio usate nelle condizioni successive

È possibile creare una variabile in un passaggio che i passaggi futuri dello stesso processo possono specificare in condizioni. Le variabili create dai passaggi sono disponibili per i passaggi futuri del processo per impostazione predefinita e non devono essere contrassegnate come variabili di output multi-processo.

Le variabili create in un passaggio di un processo presentano le limitazioni seguenti:

  • Sono inclusi nell'ambito dei passaggi dello stesso processo.
  • Sono disponibili nei passaggi successivi solo come variabili di ambiente.
  • Non è possibile usarli nello stesso passaggio che li definisce.

L'esempio seguente crea una variabile della pipeline in un passaggio e usa la variabile in una condizione script di un passaggio successivo.

steps:

# This step creates a new pipeline variable: doThing. This variable is available to subsequent steps.
- bash: |
    echo "##vso[task.setvariable variable=doThing]Yes"
  displayName: Step 1

# This step uses doThing in its condition
- script: |
    # Access the variable from Step 1 as an environment variable.
    echo "Value of doThing (as DOTHING env var): $DOTHING."
  displayName: Step 2
  condition: and(succeeded(), eq(variables['doThing'], 'Yes')) # or and(succeeded(), eq(variables.doThing, 'Yes'))

Impostazioni delle condizioni per vari risultati

La tabella seguente illustra condition le impostazioni per produrre vari risultati desiderati.

Risultato desiderato Impostazione della condizione di esempio
Eseguire se il ramo di origine è , anche se la fase padre o precedente, il processo o il passaggio non è mainriuscito o è stato annullato. eq(variables['Build.SourceBranch'], 'refs/heads/main')
Eseguire se il ramo di origine è main e la fase padre o precedente, il processo o il passaggio ha avuto esito positivo. and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
Eseguire se il ramo di origine non mainè e la fase padre o precedente, il processo o il passaggio è riuscito. and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
Eseguire per user i rami se la fase padre o precedente, il processo o il passaggio hanno avuto esito positivo. and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
Esegui per le build di integrazione continua (CI), se la fase padre o precedente, il processo o il passo hanno avuto esito positivo. and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
Eseguire se una richiesta pull ha attivato la compilazione e la fase padre o precedente, il processo o il passaggio non è riuscito. and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
Eseguire una build pianificata, anche se la fase padre o precedente, il job o il passaggio non è riuscito o è stato annullato. eq(variables['Build.Reason'], 'Schedule')
Eseguire se la variabile è impostata su System.debug, anche se la true fase padre o precedente, il processo o il passaggio non è riuscito o è stato annullato. eq(variables['System.debug'], true)

Nota

Release.Artifacts.{artifact-alias}.SourceBranch è pari a Build.SourceBranch.

Risultati delle condizioni di sistema quando una build viene annullata

L'annullamento di una compilazione non significa che tutte le fasi, i processi e i passaggi interrompono l'esecuzione. Quali processi, fasi o passaggi interrompono l'esecuzione dipendono dalle condizioni specificate e da quale punto dell'esecuzione della pipeline è stata annullata la compilazione. Se una fase, un processo o un elemento padre di un passaggio viene ignorato, la fase, il processo o il passaggio non viene eseguito, indipendentemente dalle relative condizioni.

Una fase, un processo o un passaggio viene eseguito ogni volta che le relative condizioni restituiscono true. Se una condizione non tiene conto dello stato dell'elemento padre dell'attività, l'attività potrebbe essere eseguita anche se il padre viene annullato. Per controllare se i processi, le fasi o i passaggi vengono eseguiti quando una compilazione viene annullata, includere una funzione di controllo dello stato del processo nelle condizioni.

Se si annulla una compilazione mentre è nella fase della coda ma non è ancora in esecuzione, l'intera esecuzione viene annullata, incluse tutte le altre fasi.

Nota

Se una delle condizioni consente l'esecuzione delle attività anche dopo l'annullamento della compilazione, specificare un valore per il timeout di annullamento che fornisce tempo sufficiente per il completamento delle attività dopo l'annullamento dell'esecuzione.

Risultati della condizione di fase di esempio

Negli esempi seguenti vengono illustrati i risultati di varie condizioni impostate in fasi quando la compilazione viene annullata.

Esempio di fase 1

Nella pipeline seguente, per impostazione predefinita stage2 dipende dal stage1 completamento corretto. Tuttavia, stage2 ha un condition set da eseguire ogni volta che il ramo di main origine è stage1, indipendentemente dallo stato.

Se si accoda una compilazione sul ramo main e la si annulla mentre stage1 è in esecuzione, stage2 viene comunque eseguita, perché eq(variables['Build.SourceBranch'], 'refs/heads/main') restituisce true.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
  jobs:
  - job: B
    steps:
      - script: echo 2

Esempio di fase 2

Nella pipeline seguente, per impostazione predefinita stage2 dipende stage1 dal completamento corretto. Il B processo in stage2 ha un condition set da eseguire ogni volta che il ramo di origine è main.

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione stage2 e i relativi processi non vengono eseguiti affatto, anche se la fase contiene un processo la cui condizione restituisce true.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  jobs:
  - job: B
    condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
    steps:
      - script: echo 2

Esempio di fase 3

Nella pipeline seguente, per impostazione predefinita stage2 dipende stage1 dal completamento corretto. Il passaggio all'interno del processo B ha stage2 un condition set da eseguire ogni volta che il ramo di origine è main.

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione e il processo stage2 non viene eseguito B affatto, anche se il B processo contiene un passaggio la cui condizione restituisce true. Stage2 viene ignorato completamente perché stage1 è stato annullato.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  jobs:
  - job: B
    steps:
      - script: echo 2
        condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

Risultati della condizione del processo di esempio

Negli esempi seguenti vengono illustrati i risultati di varie condizioni impostate sui processi quando la compilazione viene annullata.

Esempio di lavoro 1

Nella pipeline YAML seguente il processo B in esecuzione dipende dal processo A in esecuzione. Il B processo ha anche un condition set da eseguire ogni volta che il ramo di origine è main.

Se si accoda una build sul ramo main e la si annulla durante l'esecuzione del processo A, il processo B viene comunque eseguito, perché condition: eq(variables['Build.SourceBranch'], 'refs/heads/main') restituisce true.

jobs:
- job: A
  steps:
  - script: sleep 30
- job: B
  dependsOn: A 
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
  steps:
    - script: echo step 2.1

Se si vuole eseguire il processo B solo quando il processo A ha esito positivo e l'origine di compilazione è main, è necessario impostare su conditionand(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')).

Esempio di lavoro 2

Nella pipeline YAML seguente il processo B dipende dall'esito positivo del processo A . Il B processo ha un condition set da eseguire ogni volta che il processo A ha esito positivo e il ramo di origine di compilazione è main.

Se si accoda una compilazione nel ramo e la si annulla durante l'esecuzione main del processo A , il processo B non viene eseguito, anche se ne ha uno condition che restituisce true. La condizione sul processo B restituisce false perché il processo A non ha avuto esito positivo. Di conseguenza, il processo B e i relativi passaggi vengono ignorati.

jobs:
- job: A
  steps:
  - script: sleep 30
- job: B
  dependsOn: A 
  steps:
    - script: echo step 2.1
  condition: and(eq(variables['Build.SourceBranch'], 'refs/heads/main'), succeeded())

Risultato della condizione del passaggio di esempio

È anche possibile impostare condizioni sui passaggi. Nella pipeline seguente, il passaggio 2.3 ha un condition set da eseguire ogni volta che il ramo di origine è main.

Se si accoda una compilazione nel main branch e la si annulla mentre i passaggi 2.1 o 2.2 vengono eseguiti, il passaggio 2.3 viene comunque eseguito, perché eq(variables['Build.SourceBranch'], 'refs/heads/main') restituisce true.

steps:
  - script: echo step 2.1
  - script: echo step 2.2; sleep 30
  - script: echo step 2.3
    condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

Parametri nelle condizioni

È possibile usare i parametri nelle condizioni. L'espansione dei parametri viene eseguita prima dell'esecuzione della pipeline e sostituisce i valori racchiusi tra ${{ }} i valori dei parametri letterali. Poiché l'espansione dei parametri si verifica prima della valutazione delle condizioni, è possibile dichiarare un parametro in una pipeline e incorporare il parametro all'interno di qualsiasi condizione in tale pipeline.

Nell'esempio condition seguente vengono combinate due funzioni: succeeded() e ${{ eq(parameters.doThing, true) }}. La succeeded() funzione controlla se il passaggio precedente è riuscito. Questa funzione restituisce true anche se non è presente alcun passaggio precedente.

La ${{ eq(parameters.doThing, true) }} funzione controlla se il doThing parametro è uguale a true. Il passaggio dello script nell'esempio seguente viene eseguito perché non è presente alcun passaggio precedente ed parameters.doThing è true per impostazione predefinita.

parameters:
- name: doThing
  default: true
  type: boolean

steps:
- script: echo I did a thing
  condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})

Parametri del modello in condizioni

Quando si passa un parametro a un modello di pipeline, è possibile impostare il valore del parametro nel file modello o usare templateContext per passare il parametro al modello.

Il file modello di parameters.yml seguente dichiara il doThing parametro con un valore predefinito e true usa il parametro in una condizione del processo.

# parameters.yml
parameters:
- name: doThing
  default: true
  type: boolean

jobs:
  - job: B
    steps:
    - script: echo I did a thing
    condition: ${{ eq(parameters.doThing, true) }}

La definizione di pipeline azure-pipelines.yml seguente fa riferimento al processo nel file modello di parameters.yml . L'output della pipeline è I did a thing dovuto al fatto che il parametro doThing è true per impostazione predefinita.

# azure-pipelines.yml

extends:
  template: parameters.yml

Per altri esempi di parametri di modello, vedere informazioni di riferimento sull'utilizzo del modello.

Domande frequenti

Come è possibile attivare un processo se un processo precedente ha avuto successo ma con problemi?

È possibile usare il risultato dell'attività precedente in una condizione. Nel codice YAML seguente, la condizione eq(dependencies.A.result,'SucceededWithIssues') imposta l'esecuzione del processo B dopo l'esito positivo del processo A con problemi.

jobs:
- job: A
  steps:
  - script: echo Job A ran
- job: B
  dependsOn: A
  condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job 
  steps:
  - script: echo Job A had issues

Perché la compilazione è ancora in esecuzione dopo l'annullamento?

È possibile riscontrare questo problema se una condizione configurata in una fase non include una funzione di controllo dello stato del processo. Per risolvere il problema, aggiungere una funzione di verifica dello stato del processo alla condizione. Per altre informazioni, vedere Risultati delle condizioni quando una compilazione viene annullata.