# Azure Dev Ops Pipelines: différencier vos builds

> Il est très courant d’utiliser le même script de build pour les builds lancée automatiquement par les Pull Request (PR) et les builds lancé par l’intégration…

- Auteur: Jérôme Giacomini
- Langue: fr
- URL canonique: [Azure Dev Ops Pipelines: différencier vos builds](https://jeromegiacomini.net/fr/articles/2020/07/26/azure-dev-ops-pipelines-differencier-vos-builds)
- Publié le: 2020-07-26
- Dernière modification: 2026-09-05
- Thèmes: .NET, C#, Azure, DevOps

Il est très courant d’utiliser le même script de build pour les builds lancée automatiquement par les **Pull Request **(PR) et les builds lancé par l’intégration continue (aussi appelé **Continuous Intregration : CI**).

Cependant même si ces deux builds sont très proche, leurs besoins ne sont pas exactement les mêmes.

Dans cet article nous verrons :
- quelles sont les différences entre ces deux builds
- comment utiliser le même script [YAML](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&amp;tabs=schema%2Cparameter-schema) pour ces deux builds et désactiver les « steps » non nécessaire à nos builds.


## La problématique

### Les étapes d’une Build de PR

Quelles sont les étapes usuelle d’une build lancée sur chaque Pull Requests :
- Choix du SDK .NET Core : c’est une bonne pratique de spécifier au compilateur quel version du SDK utiliser pour avoir exactement le même comportement que votre machine [global.json](https://docs.microsoft.com/fr-fr/dotnet/core/tools/global-json?tabs=netcore3x)
- dotnet restore : avant de compiler notre application il faut restaurer les packages nuget
- dotnet build : l’étape la plus importante la build de votre application elle même
- dotnet test: cette étape lance les tests de votre application. Généralement dans mes programmes je sépare le sépare en 2 étapes tests unitaires des tests d’intégration. Valider les tests sur sur chaque PR permet de détecter **au plus tôt **quand l’évolution de votre code base casse un fonctionnement attendu.


### Les étapes d’une build de CI
- Choix du SDK .NET Core
- dotnet restore
- dotnet build
- dotnet publish : crée les binaires dans une dossier spécifique
- publish artefact : publie les artefacts (les binaires) pour qu’ils puissent être utilisé par une tache de release


La Build PR a donc une étape supplémentaire à la build de CI l’étape de l’exécution des tests.
Cette étape n’est pas nécessaire lors de la CI car elle a déjà été faite par la PullRequest rejouer les tests n’a pas de grand intérêt.

### Pourquoi des étapes différentes ?

La Build de CI quant à elle a 2 étapes supplémentaire à la build de PR, lié à la publication d’artefacts. La build de PR n’a pas besoin de créer d’artefact ni de les publier pour une release.

### Pourquoi garder un temps de build bas ?

Il est très important de garder un temps de build et release bas, et cela pour plusieurs raisons :
- car ceux ci impacte notre capacité a publier rapidement
- plus votre temps de build est long moins votre équipe aura de feedback rapide si leurs PR sont mergeable ou non ce qui peut ralentir considérablement votre capacité de delivery
- vous avez un temps d’occupation limité de vos agents de builds autant les faire travailler uniquement pour des taches dont vous avez vraiment besoin 🙂


## Ma solution

Une solution simple est tout simplement d’activer ou désactiver certaines étapes de votre “build” en fonction de son origine via [les conditions](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&amp;tabs=yaml).

Pour activer une étape lors des builds PR je vais ajouter sur chaque étape (step) le code suivant :

```yaml

condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
```


Pour activer une étape lors des builds de CI je vais ajouter sur chaque étape le code suivant :

```yaml

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


Exemple de script complet :

```yaml

#Lance la build CI lors d'un merge sur develop staging et master
trigger:
- develop
- staging
- master
# Lance la build pr sur les branches suivantes
pr:
  branches:
    include:
    - develop
    - staging
    - master

# Image de la VM utilisée
pool:
  vmImage: 'ubuntu-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:

- task: UseDotNet@2
  displayName: use dotnet SDK
  inputs:
    packageType: 'sdk'
    useGlobalJson: true

- task: DotNetCoreCLI@2
  displayName: dotnet restore
  inputs:
    command: 'restore'

- task: DotNetCoreCLI@2
  displayName: dotnet build
  inputs:
    command: 'build'
    projects: '**/*.csproj'
    arguments: '--configuration $(BuildConfiguration)'

- task: DotNetCoreCLI@2
  displayName: dotnet test
  condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
  inputs:
    command: 'test'
    projects: '**/*Test.csproj'

- task: DotNetCoreCLI@2
  displayName: dotnet publish
  condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--output $(build.artifactstagingdirectory) --no-build --configuration $(BuildConfiguration)'

- task: PublishBuildArtifacts@1
  displayName: publish artefacts
  condition: and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'
```


Happy building 🙂

## Pour aller plus loin :
- [Les conditions en YAML](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&amp;tabs=yaml)
- [YAML schema](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&amp;tabs=schema%2Cparameter-schema)
