Conditions du pipeline
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
Cet article décrit les conditions dans lesquelles une étape, un travail ou une étape Azure Pipelines s’exécute et comment spécifier différentes conditions. Pour plus de contexte sur les étapes, les travaux et les étapes, consultez Concepts clés pour Azure Pipelines.
Par défaut, un travail ou une étape s’exécute s’il ne dépend d’aucun autre travail ou étape, ou si toutes ses dépendances sont terminées et réussies. Cette exigence s’applique non seulement aux dépendances directes, mais à leurs dépendances indirectes, calculées de manière récursive.
Par défaut, une étape s’exécute si rien dans son travail n’a pas encore échoué et que l’étape qui précède immédiatement sa fin.
Vous pouvez remplacer ou personnaliser ce comportement en forçant une étape, un travail ou une étape à exécuter même si une dépendance précédente échoue ou en spécifiant une condition personnalisée.
Remarque
Cet article décrit les fonctionnalités du pipeline YAML. Pour les pipelines classiques, vous pouvez spécifier certaines conditions dans lesquelles les tâches ou travaux s’exécutent dans les options de contrôle de chaque tâche et dans les options supplémentaires d’un travail dans un pipeline de mise en production.
Conditions dans lesquelles une étape, un travail ou une étape s’exécute
Dans la définition de pipeline YAML, vous pouvez spécifier les conditions suivantes dans lesquelles une étape, un travail ou une étape s’exécute :
Uniquement lorsque toutes les dépendances directes et indirectes précédentes avec le même pool d’agents réussissent. Si vous avez des pools d’agents différents, ces phases ou travaux s’exécutent simultanément. Cette condition est la valeur par défaut si aucune condition n’est définie dans yaML.
Même si une dépendance précédente échoue, sauf si l’exécution est annulée. Utilisez
succeededOrFailed()
dans le fichier YAML pour cette condition.Même si une dépendance précédente échoue, et même si l’exécution est annulée. Utilisez
always()
dans le fichier YAML pour cette condition.Uniquement lorsqu’une dépendance précédente échoue. Utilisez
failed()
dans le fichier YAML pour cette condition.
- Conditions personnalisées.
Par défaut, les étapes, les travaux et les étapes s’exécutent si toutes les dépendances directes et indirectes réussissent. Cet état est le même que la spécification condition: succeeded()
. Pour plus d’informations, consultez la fonction d’état réussie.
Lorsque vous spécifiez une propriété pour une étape, un condition
travail ou une étape, vous remplacez la valeur par défaut condition: succeeded()
. La spécification de vos propres conditions peut entraîner l’exécution de votre étape, de votre travail ou de votre étape, même si la build est annulée. Assurez-vous que les conditions que vous écrivez tiennent compte de l’état de la phase parente ou du travail.
L’exemple YAML suivant montre les conditions et failed()
les always()
conditions. L’étape du premier travail s’exécute même si les dépendances échouent ou si la build est annulée. Le deuxième travail s’exécute uniquement si le premier travail échoue.
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
Vous pouvez également définir et utiliser des variables dans des conditions. L’exemple suivant définit et utilise une isMain
variable pour désigner main
le 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)
Important
Les conditions sont évaluées pour déterminer s’il faut démarrer une étape, un travail ou une étape. Par conséquent, rien calculé au moment de l’exécution à l’intérieur de cette unité de travail n’est disponible. Par exemple, si vous avez un travail qui définit une variable à l’aide d’une expression runtime avec $[ ]
une syntaxe, vous ne pouvez pas utiliser cette variable dans une condition personnalisée dans ce travail.
Conditions personnalisées
Si les conditions intégrées ne répondent pas à vos besoins, vous pouvez spécifier des conditions personnalisées. Vous écrivez des conditions en tant qu’expressions dans les définitions de pipeline YAML.
L’agent évalue l’expression commençant par la fonction la plus interne et se poursuit vers l’extérieur. Le résultat final est une valeur booléenne qui détermine si la tâche, le travail ou l’étape doit s’exécuter. Pour obtenir un guide complet de la syntaxe, consultez Expressions.
Si l’une de vos conditions permet à la tâche d’s’exécuter même après l’annulation de la build, spécifiez une valeur raisonnable pour le délai d’expiration de l’annulation afin que ces tâches aient suffisamment de temps après l’annulation d’une exécution par l’utilisateur.
Résultats de condition lorsqu’une build est annulée
L’annulation d’une build ne signifie pas que toutes ses étapes, travaux ou étapes arrêtent de s’exécuter. Les étapes, les travaux ou les étapes qui arrêtent de s’exécuter dépendent des conditions que vous avez spécifiées, et à quel point de l’exécution du pipeline vous avez annulé la génération. Si le parent d’une étape, d’un travail ou d’une étape est ignoré, la tâche ne s’exécute pas, quelles que soient ses conditions.
Une étape, un travail ou une étape s’exécute chaque fois que ses conditions sont évaluées true
à . Si votre condition ne prend pas en compte l’état du parent de la tâche, elle peut s’exécuter même si son parent est annulé. Pour contrôler si des étapes, des travaux ou des étapes avec des conditions s’exécutent lorsqu’une build est annulée, veillez à inclure une fonction de vérification de l’état du travail dans vos conditions.
Les exemples suivants montrent les résultats de différentes conditions définies sur des étapes, des travaux ou des étapes lorsque la build est annulée.
Exemple d’étape 1
Dans le pipeline suivant, par défaut stage2
, dépend stage1
de , mais stage2
a un condition
ensemble à exécuter chaque fois que la branche source est main
, quel que soit l’état stage1
.
Si vous mettez en file d’attente une build sur la branche et annulez-la main
pendant stage1
l’exécution, stage2
toujours s’exécute, car eq(variables['Build.SourceBranch'], 'refs/heads/main')
elle est évaluée à 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
Exemple d’étape 2
Dans le pipeline suivant, stage2
dépend stage1
par défaut. Le travail B
dans a stage2
un condition
ensemble. Si vous mettez en file d’attente une build sur la branche et annulez-la main
pendant stage1
l’exécution, stage2
ne s’exécute pas, même si elle contient un travail dont la condition est true
évaluée .
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.
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
Exemple d’étape 3
Dans le pipeline suivant, par défaut stage2
dépend stage1
de l’étape à l’intérieur du travailB
.condition
Si vous mettez en file d’attente une build sur la branche et annulez-la main
pendant stage1
l’exécution, stage2
ne s’exécute pas, même si elle contient une étape du travail B
dont la condition est true
évaluée . La raison est que stage2
est ignoré en réponse à l’annulation de 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')
Exemple de travail 1
Dans le pipeline YAML suivant, le travail B
dépend du travail A
par défaut, mais le travail B
a un condition
ensemble à exécuter chaque fois que la branche source est main
. Si vous mettez en file d’attente une build sur la branche et annulez-la main
pendant l’exécution du travail A
, la tâche B
s’exécute toujours, car eq(variables['Build.SourceBranch'], 'refs/heads/main')
elle est évaluée à 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
Si vous souhaitez que le travail B
s’exécute uniquement lorsque le travail A
réussit et que la source de build est la main
branche, vous condition
devez être and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
.
Exemple de travail 2
Dans le pipeline suivant, le travail dépend du travail B
A
par défaut. Si vous mettez en file d’attente une build sur la branche et annulez-la main
pendant l’exécution du travail A
, le travail B
ne s’exécute pas, même si son étape a une condition
valeur qui est true
évaluée .
La raison est que le travail B
a la valeur par défaut condition: succeeded()
, qui prend la valeur false
quand le travail A
est annulé. Par conséquent, le travail B
est ignoré et aucune de ses étapes ne s’exécute.
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())
Exemple d’étape
Vous pouvez également avoir des conditions sur des étapes.
Dans le pipeline suivant, l’étape 2.3 a un condition
ensemble à exécuter chaque fois que la branche source est main
. Si vous mettez en file d’attente une build sur la main
branche et que vous l’annulez pendant que les étapes 2.1 ou 2.2 sont en cours d’exécution, l’étape 2.3 s’exécute toujours, car elle true
prend la valeur eq(variables['Build.SourceBranch'], 'refs/heads/main')
.
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')
Paramètres de condition
Le tableau suivant présente des exemples condition
de paramètres pour produire différents résultats.
Remarque
Release.Artifacts.{artifact-alias}.SourceBranch
est équivalent à Build.SourceBranch
.
Résultat souhaité | Exemple de paramètre de condition |
---|---|
Exécutez si la branche source est principale, même si l’étape parente ou précédente, le travail ou l’étape a échoué ou a été annulée. | eq(variables['Build.SourceBranch'], 'refs/heads/main') |
Exécutez si la branche source est principale et que l’étape parente ou précédente, le travail ou l’étape a réussi. | and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) |
Exécutez si la branche source n’est pas principale et que l’étape parent ou précédente, le travail ou l’étape a réussi. | and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main')) |
Exécutez les branches de rubrique utilisateur, si l’étape parente ou précédente, le travail ou l’étape a réussi. | and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/')) |
Exécutez les builds d’intégration continue (CI), si l’étape parente ou précédente, le travail ou l’étape a réussi. | and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')) |
Exécutez si la génération a été déclenchée par une stratégie de branche pour une demande de tirage (pull request) et que l’étape parente ou précédente, le travail ou l’étape a échoué. | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
Exécutez une build planifiée, même si l’étape parente ou précédente, le travail ou l’étape a échoué ou a été annulée. | eq(variables['Build.Reason'], 'Schedule') |
Exécutez si une variable a la valeur true, même si l’étape parente ou précédente, le travail ou l’étape a échoué ou a été annulée. | eq(variables['System.debug'], true) |
Remarque
Vous pouvez définir une condition à exécuter si une variable a la valeur Null (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
celle du pipeline suivant :
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
Paramètres dans les conditions
L’expansion des paramètres se produit avant que les conditions ne soient prises en compte. Par conséquent, lorsque vous déclarez un paramètre dans le même pipeline qu’une condition, vous pouvez incorporer le paramètre à l’intérieur de la condition. Le script dans les exécutions YAML suivantes est parameters.doThing
vrai.
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
Le condition
pipeline précédent combine deux fonctions : succeeded()
et eq('${{ parameters.doThing }}', true)
. La fonction succeeded()
vérifie si l’étape précédente a réussi. La succeeded()
fonction retourne true
parce qu’il n’y a pas eu d’étape précédente.
La eq('${{ parameters.doThing }}', true)
fonction vérifie si le doThing
paramètre est égal à true
. Étant donné que la valeur doThing
par défaut est true
, la condition retourne true
par défaut, sauf si le pipeline définit une valeur différente.
Paramètres de modèle dans les conditions
Lorsque vous passez un paramètre à un modèle, vous devez définir la valeur du paramètre dans votre modèle ou utiliser templateContext pour transmettre le paramètre au modèle.
Par exemple, le fichier parameters.yml suivant déclare le paramètre et la doThing
valeur par défaut :
# 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) }}
Le code de pipeline fait référence au modèle parameters.yml . La sortie du pipeline est I did a thing
due au fait que le paramètre doThing
a la valeur true.
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
Pour plus d’exemples de paramètres de modèle, consultez la référence d’utilisation du modèle.
Variables de sortie de travail utilisées dans les conditions de travail suivantes
Vous pouvez rendre une variable disponible pour de futurs travaux et la spécifier dans une condition. Les variables disponibles pour les travaux futurs doivent être marquées comme variables de sortie multi-travaux à l’aide isOutput=true
de , comme dans le code suivant :
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."
Variables créées dans une étape utilisée dans les conditions d’étape suivantes
Vous pouvez créer une variable disponible pour les prochaines étapes à spécifier dans une condition. Les variables créées à partir des étapes sont disponibles pour les futures étapes par défaut et n’ont pas besoin d’être marquées comme variables de sortie à plusieurs travaux.
Il existe quelques points importants à noter sur les variables d’étendue créées à partir des étapes.
- Les variables créées à une étape d’un travail sont limitées aux étapes du même travail.
- Les variables créées dans une étape sont disponibles dans les étapes suivantes uniquement 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.
L’exemple suivant montre la création d’une variable de pipeline dans une étape et l’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 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'))
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 dans une condition. Par exemple, dans le YAML suivant, la condition eq(dependencies.A.result,'SucceededWithIssues')
autorise l’exécution du travail B
, car le travail A
a 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. Pourquoi ?
Vous pouvez rencontrer ce problème si une condition configurée dans une phase 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 pendant qu’il se trouve dans la phase de file d’attente, mais qu’il n’est pas en cours d’exécution, le travail entier est annulé, y compris toutes les autres étapes. Pour plus d’informations, consultez Les résultats de condition lorsqu’une build est annulée plus haut dans cet article.