Specificare le condizioni

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

È possibile specificare le condizioni in base alle quali eseguire ogni processo. Per impostazione predefinita, un processo o una fase viene eseguita se non dipende da altri processi o fasi o se tutti i processi o le fasi da cui dipende sono stati completati e completati. Sono incluse non solo le dipendenze dirette, ma anche le relative dipendenze, 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 personalizzare questo comportamento forzando l'esecuzione di una fase, un processo o un passaggio anche se una dipendenza precedente ha esito negativo o specificando una condizione personalizzata.

È possibile specificare le condizioni in cui verrà eseguito un passaggio, un processo o una fase.

  • Solo quando tutte le dipendenze dirette e indirette precedenti con lo stesso pool di agenti hanno avuto esito positivo. Se sono presenti pool di agenti diversi, tali fasi o processi verranno eseguiti simultaneamente. Si tratta dell'impostazione predefinita se non è presente una condizione impostata in YAML.

  • Anche se una dipendenza precedente non è riuscita, a meno che l'esecuzione non sia stata annullata. Usare succeededOrFailed() in YAML per questa condizione.

  • Anche se una dipendenza precedente non è riuscita, anche se l'esecuzione è stata annullata. Usare always() in YAML per questa condizione.

  • Solo quando una dipendenza precedente non è riuscita. Usare failed() in YAML per questa condizione.

  • Condizioni personalizzate

Per impostazione predefinita, i passaggi, i processi e le fasi vengono eseguiti se tutte le dipendenze dirette e indirette hanno avuto esito positivo. È come se si specificasse "condition: succeeded()" (vedere succeeded status function).

jobs:
- job: Foo

  steps:
  - script: echo Hello!
    condition: always() # this step will always run, even if the pipeline is canceled

- job: Bar
  dependsOn: Foo
  condition: failed() # this job will only run if Foo fails

È anche possibile usare le variabili nelle condizioni.

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)

Le condizioni vengono valutate per decidere se avviare una fase, un processo o un passaggio. Ciò significa che non sarà 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 usando $[ ] la sintassi, non è possibile usare tale variabile nella condizione personalizzata.

YAML non è supportato in TFS.

Nota

Quando si specifica la propria condition proprietà per una fase/processo/passaggio, si sovrascrive il relativo valore predefinito condition: succeeded(). Ciò può causare l'esecuzione della fase, del processo o del passaggio anche se la compilazione viene annullata. Assicurarsi di prendere in considerazione lo stato della fase padre/processo durante la scrittura delle proprie condizioni.

Abilitare una condizione personalizzata

Se le condizioni predefinite non soddisfano le proprie esigenze, è possibile specificare condizioni personalizzate.

Le condizioni vengono scritte come espressioni nelle pipeline YAML. L'agente valuta l'espressione a partire dalla funzione più interna e la risolve. Il risultato finale è un valore booleano che determina se l'attività, il processo o la fase devono essere eseguiti o meno. Per una guida completa alla sintassi, vedere l'articolo sulle espressioni.

È possibile eseguire l'attività anche dopo l'annullamento della compilazione da parte di un utente? In tal caso, specificare un valore ragionevole per il timeout di annullamento in modo che questi tipi di attività abbiano tempo sufficiente per il completamento dopo l'annullamento di un'esecuzione da parte dell'utente.

Comportamento della pipeline quando la compilazione viene annullata

Quando una compilazione viene annullata, non significa che tutte le fasi, i processi o i passaggi interrompono l'esecuzione. La decisione dipende dalla fase, dal processo o dal passaggio conditions specificato e dal punto in cui l'esecuzione della pipeline è stata annullata.

Se la condizione non tiene conto dello stato dell'elemento padre della fase/processo/passaggio, se la condizione restituisce true, la fase, il processo o il passaggio verrà eseguito, anche se l'elemento padre viene annullato. Se l'elemento padre viene ignorato, la fase, il processo o il passaggio non verranno eseguiti.

Verranno ora esaminati alcuni esempi.

In questa pipeline, per impostazione predefinita, stage2 dipende da stage1 e stage2 ha un condition set. stage2 viene eseguito solo quando il ramo di origine è main.

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

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione, verrà comunque eseguita, stage2 perché eq(variables['Build.SourceBranch'], 'refs/heads/main') restituisce true.

In questa pipeline dipende stage2 da stage1. Il processo B ha un condition set per esso.

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

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione,stage2 non verrà eseguita, anche se contiene un processo B 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.

Si supponga di avere la pipeline YAML seguente. Si noti che, per impostazione predefinita, stage2 dipende da stage1 e che script: echo 2 ha un condition set per esso.

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

Se si accoda una compilazione nel main ramo e la si annulla durante stage1 l'esecuzione,stage2 non verrà 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 .

Per evitare fasi, processi o passaggi con conditions l'esecuzione quando una compilazione viene annullata, assicurarsi di considerare lo stato del padre durante la scrittura di conditions. Per altre informazioni, vedere Funzioni di stato del processo.

Esempi

Eseguire per il ramo main, anche se annullato, anche in caso di errore

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

Eseguire per il ramo principale, se ha esito positivo

and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Eseguire se il ramo non è principale, se ha esito positivo

and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))

Eseguire per i rami dell'argomento utente, se l'operazione è riuscita

and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))

Eseguire per le compilazioni di integrazione continua (CI) se ha esito positivo

and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))

Eseguire se la compilazione viene eseguita da un criterio di ramo per una richiesta pull, in caso di errore

and(failed(), eq(variables['Build.Reason'], 'PullRequest'))

Eseguire se la compilazione è pianificata, anche se ha esito negativo, anche se annullata

eq(variables['Build.Reason'], 'Schedule')

Release.Artifacts. {artifact-alias}. SourceBranch equivale a Build.SourceBranch.

Eseguire sempre se una variabile è impostata su true, anche se annullata, anche se ha esito negativo

eq(variables['System.debug'], true)

Eseguire se una variabile è null (stringa vuota)

Poiché tutte le variabili vengono considerate come stringhe in Azure Pipelines, una stringa vuota equivale a null in questa pipeline.

variables:
- name: testEmpty
  value: ''

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

Usare un parametro modello come parte di una condizione

Quando si dichiara un parametro nella stessa pipeline in cui si dispone di una condizione, l'espansione dei parametri viene eseguita prima che vengano considerate le condizioni. In questo caso, è possibile incorporare parametri all'interno delle condizioni. Lo script in questo file YAML verrà eseguito perché parameters.doThing è true.

condition nella pipeline combina 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 parametro doThing è uguale a true. Poiché il valore predefinito per doThing è true, la condizione restituirà true per impostazione predefinita, a meno che non venga impostato un valore diverso nella pipeline.

Per altri esempi di parametri di modello, vedere Tipi di modelli e utilizzo.

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

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

Quando si passa un parametro a un modello, è necessario impostare il valore del parametro nel modello o usare templateContext per passare le proprietà ai modelli.

# 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) }}
# azure-pipeline.yml
parameters:
- name: doThing
  default: true 
  type: boolean

trigger:
- none

extends:
  template: parameters.yml

L'output di questa pipeline è I did a thing dovuto al fatto che il parametro doThing è true.

Usare la variabile di output da un processo in una condizione in un processo successivo

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

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

Usare la variabile della pipeline creata da un passaggio in una condizione in un passaggio successivo

È possibile rendere disponibile una variabile per i passaggi futuri e specificarla in una condizione. Per impostazione predefinita, le variabili create da un passaggio sono disponibili per i passaggi futuri e non devono essere contrassegnate come variabili di output multi-processo usando isOutput=true.

Per quanto riguarda l'approccio precedente e l'ambito, tenere presente alcuni aspetti importanti:

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

Di seguito è riportato un esempio di creazione di una variabile della pipeline in un passaggio e dell'uso della variabile nella condizione e nello script di un passaggio successivo.

steps:

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

# This step is able to use doThing, so it uses it in its condition
- script: |
    # You can 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 questo file YAML, ad esempio, la condizione eq(dependencies.A.result,'SucceededWithIssues') consente l'esecuzione del processo 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. Come mai?

Si verificherà questo problema se la condizione configurata nella 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 si trova nella coda, ma non è in esecuzione, l'intero processo viene annullato, incluse tutte le altre fasi.

Altre informazioni sul comportamento di una pipeline quando una compilazione viene annullata.