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 il processo non è ancora riuscito e il passaggio immediatamente precedente è stato 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 non 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(). Se si specificano condizioni personalizzate, è possibile che la fase, il processo o il passaggio vengano eseguiti anche se la compilazione viene annullata. Assicurarsi che le condizioni scritte tengano conto dello stato della fase padre o del processo.

L'esempio YAML seguente illustra le always() condizioni e failed() . Il passaggio del primo processo viene eseguito anche se le dipendenze hanno esito negativo o la compilazione viene annullata. 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

- 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 consente l'esecuzione dell'attività anche dopo l'annullamento della compilazione, specificare un valore ragionevole per il timeout di annullamento in modo che queste attività abbiano tempo sufficiente per completare dopo che l'utente annulla un'esecuzione.

Risultati delle condizioni quando una compilazione viene annullata

L'annullamento di una compilazione non significa che tutte le fasi, i processi o i passaggi interrompono l'esecuzione. Quali fasi, processi o passaggi interrompono l'esecuzione dipendono dalle condizioni specificate e da quale punto dell'esecuzione della pipeline è stata annullata la compilazione. 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 dell'elemento padre dell'attività, l'attività potrebbe essere eseguita anche se il padre viene 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 illustrati i risultati di varie condizioni impostate su fasi, processi o passaggi quando la compilazione viene annullata.

Esempio di fase 1

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

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'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 dipende stage2 per stage1 impostazione predefinita. Il processo B in stage2 ha un condition set. Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione, stage2 non viene eseguita, anche se contiene un processo la cui condizione restituisce true.

Il motivo è dovuto stage2 al false fatto che ha il valore predefinito condition: succeeded(), che restituisce quando stage1 viene annullato. Di conseguenza, stage2 viene ignorato e nessuno dei relativi processi viene eseguito.

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 stage1e il passaggio all'interno del processo B ha un condition set.

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'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 processo 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 compilazione nel ramo e la si annulla durante l'esecuzione main 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 l'origine di compilazione è il main ramo , deve condition essere and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')).

Esempio di processo 2

Nella pipeline seguente il processo B dipende dal processo A per impostazione predefinita. 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 il relativo passaggio ha un valore condition che restituisce true.

Il motivo è dovuto al fatto che il processo B ha il valore predefinito condition: succeeded(), che 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: eq(variables['Build.SourceBranch'], 'refs/heads/main')
      

Esempio di passaggio

È 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 ramo e la si annulla mentre i passaggi 2.1 o 2.2 sono in esecuzione, 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 della condizione

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
Eseguire se il ramo di origine è principale, anche se la fase padre 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'))
Eseguire per i rami dell'argomento utente, se la fase padre o precedente, il processo o il passaggio hanno avuto esito positivo. and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
Eseguire per compilazioni di integrazione continua (CI), se la fase padre o precedente, il processo o il passaggio hanno avuto esito positivo. and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
Eseguire se la compilazione è stata attivata da un criterio di ramo per una richiesta pull e la fase padre o precedente, il processo o il passaggio non è riuscito. and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
Eseguire per una compilazione pianificata, anche se la fase padre o precedente, il processo o il passaggio non è riuscito o è stato annullato. eq(variables['Build.Reason'], 'Schedule')
Eseguire se una variabile è impostata su true, anche se la fase padre o precedente, il processo o il passaggio non è riuscito 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: ${{ 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 file di parameters.yml seguente dichiara il parametro e il doThing 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 dovuto al fatto che il parametro doThing è true.

# 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 processo successive

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

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 un passaggio usato nelle condizioni 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-processo.

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

  • 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 esito positivo con problemi?

È possibile usare il risultato del processo precedente in una condizione. Ad esempio, nel codice YAML seguente, la condizione eq(dependencies.A.result,'SucceededWithIssues') consente l'esecuzione del processo B perché il processo A ha avuto 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 controllo dello stato del processo alla condizione.

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