Spécifier des conditions

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

Vous pouvez spécifier les conditions d’exécution de chaque phase, travail ou étape. Par défaut, un travail ou un index s’exécute s’il ne dépend d’aucun autre travail ou index, ou si tous les travaux ou index dont il dépend sont terminés et réussis. Cela inclut non seulement les dépendances directes, mais aussi leurs dépendances, calculées de manière récursive. Par défaut, une étape s’exécute si rien dans son travail n’a encore échoué et que l’étape qui la précède immédiatement est terminée. Vous pouvez personnaliser ce comportement en forçant l’exécution d’une phase, d’un travail ou d’une étape même si une dépendance précédente échoue ou en spécifiant une condition personnalisée.

Vous pouvez spécifier les conditions d’exécution d’une étape, d’un travail ou d’une phase.

  • Uniquement lorsque toutes les dépendances directes et indirectes précédentes ont réussi avec le même pool d’agents. Si vous avez des pools d’agents différents, ces phases ou travaux s’exécutent simultanément. Il s’agit de la valeur par défaut si aucune condition n’est définie dans le fichier YAML.

  • Même si une dépendance précédente a échoué, sauf si l’exécution a été annulée Utilisez succeededOrFailed() dans le fichier YAML pour cette condition.

  • Même si une dépendance précédente a échoué, même si l’exécution a été annulée Utilisez always() dans le fichier YAML pour cette condition.

  • Seulement quand une dépendance précédente a échoué Utilisez failed() dans le fichier YAML pour cette condition.

  • Conditions personnalisées

Par défaut, les étapes, les travaux et les phases s’exécutent si toutes les dépendances directes et indirectes ont abouti. Cela revient à spécifier « condition: succeeded() » (consultez fonction d’état réussie).

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

Vous pouvez également utiliser des variables dans des conditions.

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)

Les conditions sont évaluées pour déterminer si un index, un travail ou une étape doivent démarrer. Cela signifie que rien de ce qui est calculé au moment de l’exécution à l’intérieur de cette unité de travail ne sera disponible. Par exemple, si vous avez un travail qui définit une variable à l’aide d’une expression d’exécution qui utilise la syntaxe $[ ], vous ne pouvez pas utiliser cette variable dans votre condition personnalisée.

YAML n’est pas pris en charge dans TFS.

Notes

Lorsque vous spécifiez votre propre propriété condition pour un index/un travail/une étape, vous remplacez sa valeur par défaut condition: succeeded(). Cela peut entraîner l’exécution de votre index/travail/étape même si la build est annulée. Veillez à prendre en compte l’état de l’index/du travail parent quand vous écrivez vos propres conditions.

Activer une condition personnalisée

Si les conditions intégrées ne répondent pas à vos besoins, alors vous pouvez spécifier des conditions personnalisées.

Les conditions sont écrites en tant qu’expressions dans les pipelines YAML. L’agent évalue l’expression en commençant par la fonction la plus intérieure jusqu’à la fin. Le résultat final est une valeur booléenne qui détermine si la tâche, le travail ou la phase doit s’exécuter ou non. Consultez l’article sur les expressions pour obtenir un guide complet sur la syntaxe.

L’une de vos conditions permet-elle l’exécution de la tâche même après l’annulation de la build par un utilisateur ? Si c’est le cas, spécifiez une valeur raisonnable pour le délai d’annulation afin que ces types de tâches aient suffisamment de temps pour se terminer après l’annulation d’une exécution par l’utilisateur.

Comportement du pipeline lors de l’annulation de la build

Lorsqu’une build est annulée, cela ne signifie pas que tous ses index, travaux ou étapes s’arrêtent. La décision dépend des conditions d’index, de travail ou d’étape que vous avez spécifiées et à quel moment de l’exécution du pipeline vous avez annulé la build.

Si votre condition ne tient pas compte de l’état du parent de votre index/travail/étape, alors si la condition prend la valeur true, votre index, travail ou étape s’exécute, même si son parent est annulé. Si son parent est ignoré, alors votre index, travail ou étape ne s’exécutera pas.

Prenons quelques exemples.

Dans ce pipeline, par défaut, stage2 dépend de stage1 et stage2 a une condition définie. stage2 s’exécute uniquement lorsque la branche source est 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

Si vous mettez en file d’attente une build sur la branche main et que vous l’annulez alors que stage1 est en cours d’exécution, stage2 s’exécute quand même, car eq(variables['Build.SourceBranch'], 'refs/heads/main') prend la valeur true.

Dans ce pipeline, stage2 dépend de stage1. Le travail B a une condition définie pour lui.

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

Si vous mettez en file d’attente une build sur la branche main et que vous l’annulez alors que stage1 est en cours d’exécution, stage2ne s’exécute pas, même s’il contient un travail B dont la condition prend la valeur true. La raison est que stage2 a la valeur par défaut condition: succeeded(), qui prend la valeur false quand stage1 est annulé. Par conséquent, stage2 est ignoré et aucun de ses travaux ne s’exécute.

Supposons que vous ayez le pipeline YAML suivant. Notez que, par défaut, stage2 dépend de stage1 et que script: echo 2 a une condition définie pour lui.

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

Si vous mettez en file d’attente une build sur la branche main et que vous l’annulez alors que stage1 est en cours d’exécution, stage2ne s’exécute pas, même s’il contient une étape dans un travail B dont la condition prend la valeur true. La raison est que stage2 est ignoré en réponse à l’annulation de stage1.

Pour empêcher l’exécution d’index, de travaux ou d’étapes qui ont une conditions quand une build est annulée, veillez à tenir compte de l’état de leur parent pour écrire la conditions. Pour plus d’informations, consultez Fonctions de vérification des états de travail.

Exemples

Exécuter pour la branche primaire, même en cas d’annulation, même en cas d’échec

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

Exécuter pour la branche primaire, en cas de réussite

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

Exécuter si la branche n’est pas primaire, en cas de réussite

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

Exécuter pour les branches de rubrique utilisateur, en cas de réussite

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

Exécuter pour les builds d’intégration continue (CI), en cas de réussite

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

Exécuter si la build est exécutée par une stratégie de branche pour une demande de tirage, en cas d’échec

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

Exécuter si la build est planifiée, même en cas d’échec, même en cas d’annulation

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

Release.Artifacts.{artifact-alias}.SourceBranch équivaut à Build.SourceBranch.

Toujours exécuter si une variable a la valeur true, même en cas d’annulation, même en cas d’échec

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

Exécuter si une variable est nulle (chaîne vide)

Étant donné que toutes les variables sont traitées comme des chaînes dans Azure Pipelines, une chaîne vide équivaut à null dans ce pipeline.

variables:
- name: testEmpty
  value: ''

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

Utiliser un paramètre de modèle dans le cadre d’une condition

Lorsque vous déclarez un paramètre dans le même pipeline que celui dans lequel vous avez une condition, le développement des paramètres se produit avant que les conditions ne soient prises en compte. Dans ce cas, vous pouvez incorporer des paramètres dans des conditions. Le script inclus dans ce fichier YAML s’exécute car parameters.doThing a la valeur true.

La condition dans le pipeline combine deux fonctions : succeeded() et eq('${{ parameters.doThing }}', true). La fonction succeeded() vérifie si l’étape précédente a réussi. La fonction succeeded() retourne true, car il n’y avait pas d’étape précédente.

La fonction eq('${{ parameters.doThing }}', true) vérifie si le paramètre doThing est égal à true. Étant donné que la valeur par défaut de doThing est « true », la condition retourne « true » par défaut, sauf si une autre valeur est définie dans le pipeline.

Pour obtenir plus d’exemples de paramètres de modèle, consultez Types de modèles et utilisation.

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

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

Lorsque vous passez un paramètre à un modèle, vous avez besoin de définir la valeur du paramètre dans votre modèle ou d’utiliser templateContext pour passer des propriétés aux modèles.

# 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

La sortie de ce pipeline est I did a thing car le paramètre doThing a la valeur true.

Utiliser la variable de sortie d’un travail dans une condition dans un travail ultérieur

Vous pouvez rendre une variable disponible pour de futurs travaux et la spécifier dans une condition. Les variables disponibles pour de futurs travaux doivent être marquées comme variables de sortie multi-travaux à l’aide de 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."

Utiliser la variable de pipeline créée à partir d’une étape dans une condition dans une étape ultérieure

Vous pouvez rendre une variable disponible pour de futures étapes et la spécifier dans une condition. Par défaut, les variables créées à partir d’une étape sont disponibles pour de futures étapes et n’ont pas besoin d’être marquées comme variables de sortie multi-travaux à l’aide de isOutput=true.

Il existe quelques points importants à noter sur l’approche et l’étendue ci-dessus :

  • Les variables créées dans une étape incluse dans un travail sont étendues aux étapes incluses dans ce même travail.
  • Les variables créées dans une étape sont uniquement disponibles dans les étapes ultérieures en tant que variables d’environnement.
  • Les variables créées dans une étape ne peuvent pas être utilisées dans l’étape qui les définit.

Voici un exemple de création d’une variable de pipeline dans une étape et d’utilisation de la variable dans la condition et le script d’une étape ultérieure.

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

Questions fréquentes (FAQ)

Comment déclencher un travail si un travail précédent a réussi avec des problèmes ?

Vous pouvez utiliser le résultat du travail précédent. Par exemple, dans ce fichier YAML, la condition eq(dependencies.A.result,'SucceededWithIssues') autorise l’exécution du travail, car le travail A est réussi avec des problèmes.

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

J’ai annulé ma build, mais elle est toujours en cours d’exécution. Que se passe-t-il ?

Vous allez rencontrer ce problème si la condition configurée dans l’index n’inclut pas de fonction de vérification de l’état du travail. Pour résoudre le problème, ajoutez une fonction de vérification de l’état du travail à la condition. Si vous annulez un travail alors qu’il se trouve dans la file d’attente, mais qu’il n’est pas en cours d’exécution, l’ensemble du travail est annulé, y compris tous les autres index.

Découvrez-en plus sur le comportement d’un pipeline lorsqu’une build est annulée.