Contexte et objectifs
Dans un dépôt Azure DevOps, deux modules partageaient des définitions de build et de release quasi‑identiques ; un troisième aurait nécessité un troisième couple. La chaîne de livraison comptait cinq définitions : un décideur de changement, deux builds et deux releases. L’objectif était de réduire la duplication, de simplifier la maintenance et d’éviter les modifications parallèles sur plusieurs pipelines.
Architecture consolidée
Le nouveau schéma repose sur trois définitions : un décideur unique, un build générique et une release contenant un stage par module. Le décideur, seul déclencheur d’intégration continue, analyse les chemins modifiés, puis place le build générique dans la file avec les paramètres service et module. Chaque module possède désormais une entrée de mappage dans le décideur, un groupe de variables et un stage de déploiement dédié. Le nommage suit le modèle <Produit>.<Service>.<Portée>.<Type>, ce qui rend les identifiants explicites et facilite la recherche.
Mécanismes de paramétrage et de tags
Le décideur transmet les valeurs via l’API Azure DevOps Build REST, qui attend un paramètre JSON encodé en chaîne. Exemple :
BODY="{\"definition\":{\"id\":$BUILD_ID}, \"sourceBranch\":\"$(Build.SourceBranch)\", \"sourceVersion\":\"$(Build.SourceVersion)\", \"parameters\":\"{\\\"service\\\":\\\"$SERVICE\\\",\\\"module\\\":\\\"$MODULE\\\"}\"}"Les variables doivent conserver l’option allowOverride: true (Settable at queue time) ; sinon le décideur peut échouer lors du passage des valeurs. Le build générique, dépourvu de déclencheur CI, dérive les noms d’image et de chart à partir des paramètres, publie l’artifact et ajoute un tag de run sous la forme module-b. La forme module:module-b a été rejetée par Azure DevOps à cause du deux‑points dans le chemin de requête.
Azure DevOps autorise des filtres de tags à deux niveaux : le déclencheur de release (empêche la création d’une release si le tag ne correspond pas) et la condition d’étape (détermine quel stage s’exécute). Ainsi, le tag module-a active le stage A, tandis que le stage B reçoit module-b et est ignoré avec le statut « Artifact conditions not met », ce qui n’est pas considéré comme une erreur de déploiement.
Résultats et limites
La consolidation a supprimé un build et un release dupliqués, passant de cinq à trois définitions. Le décideur garantit que chaque exécution est liée à un commit précis ; un push ultérieur ne peut pas modifier le contenu du build déjà lancé. Le renommage des définitions a conservé leurs identifiants internes, évitant la rupture des références d’exécution, bien que les métadonnées d’interface affichent encore les anciens noms jusqu’à une mise à jour manuelle.
Des contraintes subsistent : les politiques de validation de build conservent les anciens noms et doivent être ajustées séparément. La suppression d’un build référencé par une release renvoie un HTTP 409, obligeant à désactiver le déclencheur, à nettoyer les références et à archiver la définition. L’ajout d’un nouveau module ne nécessite plus de build dédié, mais implique la création d’une entrée de mappage, d’un groupe de variables et d’un stage de release, ce qui reste une charge administrative.