Bonnes pratiques pour créer des pipelines Azure YAML maintenables

De premier abord, créer un pipeline Azure n’est pas très compliqué. Les exemples sont nombreux et la documentation est bien fournie.

Mais (oui, il y a un mais) :

  • Azure Devops évolue régulièrement, très régulièrement. Il peut donc être difficile de suivre les évolutions dans le temps.
  • Azure Devops permet d’associer / mélanger beaucoup de technologies. Les solutions de builds sont donc nombreuses. Il peut s’avérer compliquer de toutes les maitriser. Si l’on utilise plusieurs technologies dans un même projet, les builds sont plus compliquées.
  • Azure Devops permet de déployer / publier ses applications sur de nombreuses plateformes. Toutes les maitriser passe par une période plus ou moins longue d’apprentissage et de tests (beaucoup de tests).

Pour ces raisons, la création d’un pipeline doit suivre quelques règles qui permettront de :

  • Faciliter la découverte des pipelines YAML.
  • Faciliter la maintenance dans le temps.
  • Faciliter la lecture du pipeline YAML.
  • Faciliter la réutilisation du code YAML déjà éprouvé.

Pour arriver à tenir ces objectifs, j’applique les bonnes pratiques suivantes :

  • En entête de chaque document YAML, laisser la documentation de Microsoft relative à la technologie utilisée (Builds .net core, .net classic, java…).
  • Créer un dossier Builds (ou Pipelines) à la racine du repository pour y ajouter et versionner le YAML. Le code source de l’application doit être dans un dossier Sources ou Codes. Cela évite de voir ce que l’on rencontre sur trop de projets où tout est mélangé (parfois avec la documentation).
  • Créer des templates YAML et les placer dans un dossier Templates. Ces templates contiendront les différentes actions qu’Azure Pipeline devra entreprendre pour vous. Le YAML à la racine du dossier Builds ne contiendra que les paramètres de builds spécifiques à l’application courante. Le ou les templates pourront être copiés et réutilisés pour d’autres projets.
  • Regrouper les tâches qui ont une finalité commune sous une ligne de commentaire (exemple Tests, Npm, Nuget). Ajouter une ligne vide après l’ensemble de tâches pour faciliter la lecture.
  • Utiliser la propriété displayName sur chaque task pour indiquer son rôle. On peut aussi le faire sur les jobs et stages pour faciliter le debug des pipelines.
  • Utiliser la syntaxe des tasks longues (ex : task: nom@version). L’utilisation des versions raccourcies est profitable quand chacun connait les raccourcies. Dans l’optique d’une maintenabilité optimale, vous n’êtes pas en mesure de vous assurer que chacun pourra comprendre votre code. De plus les tasks, on l’avantage de toutes avoir la même structure. Ce qui rend la lecture plus fluide et rapide. Contrairement aux versions raccourcies qui ont toutes des structures différentes (même si certaines se ressemblent).

Concernant le paramétrage :

  • Toujours donner un nom aux artefacts de sortie de build. Cela facilite le debug et se révèle très pratique le jour où vous devez produire plusieurs artefacts.
  • Dans les templates, toujours ajouter des paramètres avec des valeurs à défaut. Cela ajoute un niveau de documentation et permet d’éviter les erreurs lors de la réutilisation d’un template.

Pour facilite la compréhension de ces quelques règles, voici un exemple :


Contenu du template build-jobs.yml créé dans le dossier templates.

# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4

# Default values
parameters:
  platform: 'x64'
  configuration: 'Release'
  artifact: 'artifact'

# Jobs
jobs:
- job: 'Build'
  displayName: 'Build & Test & Publish'
  steps:
  # Manage nuget packages
  - task: NuGetToolInstaller@1
    displayName: 'Check nuget platform'    
  - task: NuGetCommand@2
    displayName: 'Get packages'
    inputs:
      restoreSolution: '**/*.sln'

  # Build (removed autoparameterizationwebconfigconnectionstrings)
  - task: VSBuild@1
    inputs:
      solution: '**/*.sln'
      msbuildArgs:
        '/p:DeployOnBuild=true
        /p:WebPublishMethod=Package
        /p:PackageAsSingleFile=true
        /p:SkipInvalidConfigurations=true
        /p:PackageLocation="$(build.artifactStagingDirectory)"
        /p:autoparameterizationwebconfigconnectionstrings=false'
      platform: '${{parameters.platform}}'
      configuration: '${{parameters.configuration}}'

  # Tests
  - task: VisualStudioTestPlatformInstaller@1
    displayName: 'Check Test platform'
    inputs:
      versionSelector: latestStable
  - task: VSTest@2
    displayName: 'Run tests'
    inputs:
      platform: '${{parameters.platform}}'
      configuration: '${{parameters.configuration}}'
      codeCoverageEnabled: false

  # Publish
  - task: PublishBuildArtifacts@1
    displayName: 'Publish artifact'
    inputs:
      PathtoPublish: '$(build.artifactStagingDirectory)'
      ArtifactName: '${{parameters.artifact}}'


Contenu du fichier build.yml qui utilise le template.

# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4

pool: MyPool

variables:
  configuration: Release
  platform: x64
  artifact: MyWebApp

trigger:
- master

stages:
# Build / Test / Publish artefacts
- stage: Build
  displayName: 'Build stage'
  jobs:
  - template: templates/build-jobs.yml
    parameters:
      configuration: $(configuration)
      platform: $(platform)
      artifact: $(artifact)
Jérémy Jeanson

Comments

You have to be logged in to comment this post.