Bonnes pratiques pour créer des pipelines Azure YAML maintenables
Date of publication
4/1/2020
No comments
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
(ouPipelines
) à la racine du repository pour y ajouter et versionner le YAML. Le code source de l’application doit être dans un dossierSources
ouCodes
. 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 dossierBuilds
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 lesjobs
etstages
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)