Condividi tramite


Condizioni della pipeline

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

Questo articolo descrive le condizioni in cui viene eseguita una fase, un processo o un passaggio di Azure Pipelines e come specificare condizioni diverse. Per altre informazioni di contesto su fasi, processi e passaggi, vedere Concetti chiave per Azure Pipelines.

  • Per impostazione predefinita, un processo o una fase viene eseguita se non dipende da altri processi o fasi o se tutte le relative dipendenze sono completate e riuscite. Questo requisito si applica non solo alle dipendenze dirette, ma 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.

È possibile eseguire l'override o personalizzare questo comportamento forzando una fase, un processo o un passaggio per l'esecuzione anche se una dipendenza precedente ha esito negativo o specificando una condizione personalizzata.

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 in cui viene eseguita una fase, un processo o un passaggio

Nella definizione della pipeline YAML è possibile specificare le condizioni seguenti in cui viene eseguita una fase, un processo o un passaggio:

  • Solo quando tutte le dipendenze dirette e indirette precedenti con lo stesso pool di agenti hanno esito positivo. Se sono presenti pool di agenti diversi, tali fasi o processi vengono eseguiti simultaneamente. Questa condizione è l'impostazione predefinita se non viene impostata alcuna condizione in YAML.

  • Anche se una dipendenza precedente ha esito negativo, a meno che l'esecuzione venga annullata. Usare succeededOrFailed() in YAML per questa condizione.

  • Anche se una dipendenza precedente ha esito negativo e anche se l'esecuzione viene annullata. Usare always() in YAML per questa condizione.

  • Solo quando una dipendenza precedente ha esito negativo. Usare failed() in YAML per questa condizione.

  • Condizioni personalizzate.

Per impostazione predefinita, le fasi, i processi e i passaggi vengono eseguiti se tutte le dipendenze dirette e indirette hanno esito positivo. Questo stato equivale a specificare condition: succeeded(). Per altre informazioni, vedere Funzione di stato riuscita.

Quando si specifica una proprietà per una condition fase, un processo o un passaggio, si sovrascrive il valore predefinito condition: succeeded(). Specificando condizioni personalizzate, è possibile che la fase, il processo o il passaggio vengano eseguiti anche se la build viene annullata. Assicurarsi che le condizioni scritte tengano conto dello stato della fase principale o del lavoro.

L'esempio YAML seguente mostra le condizioni always() e failed(). La fase della prima attività viene eseguita anche se le dipendenze falliscono o la compilazione viene annullata. Nella seconda attività di script exit 1, Foo costringe il processo a fallire. Il secondo processo viene eseguito solo se il primo processo ha esito negativo.

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

È anche possibile impostare e usare variabili in condizioni. Nell'esempio seguente viene impostata e utilizzata una isMain variabile per designare main come .Build.SourceBranch

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)

Importante

Le condizioni vengono valutate per determinare se avviare una fase, un processo o un passaggio. Di conseguenza, non è disponibile alcun calcolo in fase di esecuzione all'interno di tale unità di lavoro. Ad esempio, se si dispone di un processo che imposta una variabile usando un'espressione di runtime con $[ ] sintassi, non è possibile usare tale variabile in una condizione personalizzata in tale processo.

Condizioni personalizzate

Se le condizioni predefinite non soddisfano le proprie esigenze, è possibile specificare condizioni personalizzate. Le condizioni sono scritte 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 l'attività, il processo o la fase. Per una guida completa alla sintassi, vedere Espressioni.

Se una delle condizioni permette l'esecuzione dell'attività anche dopo che la compilazione è annullata, specificare un valore ragionevole per il timeout di annullamento in modo che queste attività abbiano tempo sufficiente per completarsi dopo che l'utente annulla un'esecuzione.

Risultati delle condizioni di sistema quando una build viene annullata

L'annullamento di una compilazione non significa che tutte le fasi, i processi o i passaggi interrompano l'esecuzione. Le fasi, i processi o i passaggi che si interrompono dipendono dalle condizioni specificate e dal momento in cui hai annullato la compilazione durante l'esecuzione della pipeline. Se viene ignorata una fase, un processo o un elemento padre di un passaggio, l'attività non viene eseguita, indipendentemente dalle relative condizioni.

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

Negli esempi seguenti vengono mostrati i risultati delle diverse condizioni impostate su fasi, attività o passaggi quando il build viene annullato.

Esempio di fase 1

Nella pipeline seguente, per impostazione predefinita stage2 dipende da stage1, ma stage2 è impostato per essere eseguito ogni volta che il ramo di origine è condition, indipendentemente dallo stato di main.

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, stage2 dipende da stage1 per impostazione predefinita. Il lavoro B in stage2 ha un condition set. Se si accoda una compilazione sul ramo main e la si annulla mentre stage1 è in esecuzione, stage2 non viene eseguita, anche se contiene un'attività la cui condizione viene valutata come 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 da stage1, e il passaggio all'interno del processo B ha un condition impostato.

Se si accoda una compilazione sul ramo main e la si annulla mentre stage1 è in esecuzione, stage2 non viene eseguita, anche se contiene un passaggio nel processo B la cui condizione restituisce true. Il motivo è dovuto al fatto che stage2 viene ignorato in risposta all'annullamento stage1 .

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

Esempio di lavoro 1

Nella pipeline YAML seguente il processo B dipende dal processo A per impostazione predefinita, ma il processo B è condition impostato per l'esecuzione 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é 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 la sorgente di build è il branch main, condition dovrebbe essere and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')).

Esempio di lavoro 2

Nella pipeline seguente il processo B dipende dal processo A per impostazione predefinita. Se si accoda una compilazione nel ramo main e la si annulla mentre il processo A è in esecuzione, il processo B non viene eseguito, anche se il relativo passaggio ha un condition che si valuta come true.

Il motivo è che il processo B restituisce false quando il processo A viene annullato. Di conseguenza, il processo B viene ignorato e nessuno dei relativi passaggi viene eseguito.

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

Esempio di passo

È anche possibile avere 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')

Impostazioni delle condizioni

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

Nota

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

Risultato desiderato Impostazione della condizione di esempio
Esegui se il ramo di origine è il principale, anche se la fase superiore o precedente, il processo o il passaggio non è riuscito o è stato annullato. eq(variables['Build.SourceBranch'], 'refs/heads/main')
Eseguire se il ramo di origine è principale 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 è principale e la fase padre o precedente, il processo o il passaggio ha avuto esito positivo. and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
Esegui per i branch relativi all'utente, se la fase padre o quella precedente, il job o lo step 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'))
Esegui se la compilazione è stata attivata da una politica di ramo per una pull request e la fase padre o precedente, il processo o il passaggio ha fallito. 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')
Esegui se una variabile è impostata su true, anche se la fase, il processo o il passaggio padre o precedente è fallito o è stato annullato. eq(variables['System.debug'], true)

Nota

È possibile impostare una condizione da eseguire se una variabile è null (stringa vuota). Poiché tutte le variabili vengono considerate come stringhe in Azure Pipelines, 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, '')

Parametri nelle condizioni

L'espansione dei parametri avviene prima che vengano considerate le condizioni. Pertanto, quando si dichiara un parametro nella stessa pipeline di una condizione, è possibile incorporare il parametro all'interno della condizione. Lo script nel codice YAML seguente viene eseguito perché parameters.doThing è true.

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

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

condition Nella pipeline precedente vengono combinate due funzioni: succeeded() e ${{ eq(parameters.doThing, true) }}. La succeeded() funzione controlla se il passaggio precedente è riuscito. La succeeded() funzione restituisce true perché non è stato eseguito alcun passaggio precedente.

La ${{ eq(parameters.doThing, true) }} funzione controlla se il doThing parametro è uguale a true. Poiché il valore predefinito per doThing è true, la condizione restituisce true per impostazione predefinita, a meno che la pipeline non imposti un valore diverso.

Parametri del modello in condizioni

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

Ad esempio, il seguente file parameters.yml dichiara il parametro doThing e il suo valore predefinito:

# parameters.yml
parameters:
- name: doThing
  default: true # value passed to the condition
  type: boolean

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

Il codice della pipeline fa riferimento al modello di parameters.yml . L'output della pipeline è I did a thing poiché il parametro doThing è vero.

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

trigger:
- none

extends:
  template: parameters.yml

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

Variabili di output del processo usate nelle condizioni di lavoro successive

È possibile rendere disponibile una variabile per i processi futuri e specificarla in una condizione. Le variabili disponibili per i lavori futuri devono essere contrassegnate come variabili di output multi-job usando isOutput=true, come nel seguente codice:

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

Variabili create in una fase usate nelle condizioni di fase successive

È possibile creare una variabile disponibile per i passaggi futuri da specificare in una condizione. Le variabili create dai passaggi sono disponibili per i passaggi futuri per impostazione predefinita e non devono essere contrassegnate come variabili di output multi-job.

Esistono alcuni aspetti importanti da notare sulla definizione dell'ambito delle variabili create dai passaggi procedurali.

  • Le variabili create in un passaggio di un processo hanno come ambito i passaggi dello stesso processo.
  • Le variabili create in un passaggio sono disponibili nei passaggi successivi solo come variabili di ambiente.
  • Le variabili create in un passaggio non possono essere usate nel passaggio che li definisce.

Nell'esempio seguente viene illustrata la creazione di una variabile della pipeline in un passaggio e l'uso della variabile nella condizione e nello 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 is able to use doThing, so it 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'))

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. Ad esempio, nel codice YAML seguente, la condizione eq(dependencies.A.result,'SucceededWithIssues') consente l'esecuzione del processo B dopo che il processo A ha esito positivo con problemi.

jobs:
- job: A
  displayName: Job A
  continueOnError: true # next job starts even if this one fails
  steps:
  - script: echo Job A ran
  - script: exit 1

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

Ho annullato la compilazione, ma è ancora in esecuzione. Perché?

È 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.

Se si annulla un processo mentre è nella fase di coda ma non è in esecuzione, l'intero processo viene annullato, incluse tutte le altre fasi. Per ulteriori informazioni, vedere Risultati delle condizioni quando una compilazione viene annullata all'inizio di questo articolo.