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 stage1
e 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', succeeded())
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: 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 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.