Cet article a pour objectif d’introduire l’usage de YAML Pipelines et de vous expliquer au travers d’un tutoriel de 4 étapes, comment il peut vous aider à gérer les pipelines de build et release, sans que vous changiez vos outils et habitudes.

 

Comprendre YAML Pipelines

Pour commencer, partons de zéro pour définir ce qu’est YAML. C’est simplement un standard destiné à la sérialisation de données, comme XML ou JSON, à la différence qu’il se veut plus lisible. Bien qu’assez ancien, l’adoption du YAML a connu un fort accroissement ces dernières années. En effet, son utilisation va de l’export de données par phpMyAdmin à la configuration d’un cluster Kubernetes en passant par les playbooks Ansible et bien sûr, les définitions de build dans Azure DevOps.  Notons aussi que plus récemment, YAML a été utilisé pour la définition des workflows dans GitHub Actions.

Puisque les fichiers YAML sont avant tout des fichiers textes, ils peuvent être versionnés dans un dépôt Git par exemple et leur maintenance entre alors dans le processus bien connu des développeurs.

L’un des objectifs de la mise en place des définitions YAML dans Azure DevOps est de permettre aux développeurs de gérer leurs pipelines de build et de release comme ils gèrent leur code, avec les mêmes outils et suivant les mêmes habitudes.

L’utilisation de fichiers de définition de build n’est pas nouvelle. On retrouve ce principe dans la plupart des outils de CI (pour Continuous Integration) du marché, tel que Jenkins avec les fichiers Groovy, GitLab CI, Travis CI, Circle CI. On parle alors de « Pipeline as Code ».

 

 

L’association Azure DevOps & YAML

Microsoft a beaucoup investi ces derniers mois pour apporter de nombreuses fonctionnalités aux développeurs. Avec la montée en puissance de DevOps, les outils de CI/CD prennent de plus en plus d’importance.

Au fil des livraisons, l’expérience YAML a grandement été enrichie et il n’y a pas une seule nouvelle version qui ne propose diverses améliorations ou ajouts de possibilités.

 

Une des fonctionnalités clés de ces définitions de release est d’ailleurs toujours en preview, mais vous pouvez l’activer depuis vos paramètres de profil, il s’agit des définitions multi-stages.

Ces “stages” vont vous permettre de séquencer différentes étapes de build, de test, mais également de déploiement.

 

Le designer a lui aussi été grandement amélioré. Au départ, ce n’était qu’un simple éditeur de texte. Aujourd’hui, il dispose d’un panneau latéral permettant d’ajouter des tâches en les configurant avec le même écran de saisie que le designer classique (graphique). Plus récemment, il est devenu possible de configurer une tâche déjà présente grâce à cette même interface.

L’éditeur de texte, lui, embarque Monaco, le même moteur que VS Code. Il est par exemple possible de commenter un bloc de code en sélectionnant une ou plusieurs lignes puis en utilisant le raccourci Ctrl + K, C. La frappe multi-curseur est également présente.

 

De plus, les définitions YAML sont tellement mises en avant par Microsoft qu’il en devient presque compliqué de créer une définition par l’éditeur classique. Par défaut toute création se fait en YAML. Il faut cliquer sur le lien “Use classic editor” pour être redirigé vers l’éditeur habituel. Et même alors, dans la liste des templates proposés, le template YAML arrive en première position dans la liste.

 

“Get started” en 4 étapes 

 

Maintenant que je vous ai présenté YAML, entrons dans la pratique et créons notre première définition de build !

Pour faire simple, nous allons partir d’un projet web en .NET Core, que nous allons pousser sur un repo Git dans Azure DevOps. Nous pourrions tout aussi bien archiver du code Javascript sur GitHub. Azure DevOps n’est pas limité aux technos Microsoft, bien au contraire, c’est aujourd’hui un système très ouvert.

 

1ère étape – création d’un projet Azure DevOps

Pour débuter, vous pouvez créer gratuitement votre premier projet. Pour cela il vous suffit d’avoir un compte Microsoft ou un compte GitHub et de vous rendre à l’adresse https://dev.azure.com, puis de vous laisser guider.

 

Cliquez sur « New project » :

bouton new project

 

Saisissez le nom, la visibilité. Laissez les options avancées par défaut, et cliquez sur « Create »

Create new project

 

2ème étape – connexion à notre dépôt Git

Pour cela, rien de plus simple. Toujours depuis Azure DevOps, ouvrez le menu « Repos » puis « Files ».

Azure DevOps vous propose plusieurs options pour vous connecter. Nous allons simplement initialiser notre repo avec un fichier “.gitignore” optimisé pour Visual Studio.

nouveau repo

 

 

Voilà, notre repo distant est créé, nous n’avons plus qu’à le cloner en local avec l’outil de notre choix. Ici nous utiliseront Visual Studio Code.

clone repository

 

Votre navigateur va vous demander l’autorisation d’ouvrir VS Code. Après avoir accepté, celui-ci se lance et vous demande de lui indiquer le répertoire local où cloner le repo.

 

 

3ème étape – création d’un projet web

Lorsque le clonage du dépôt est terminé, ouvrez une invite de commande dans le répertoire qui contient votre repo git puis créez un nouveau projet .NET Core à l’aide de dotnet CLI :

code web project

 

Faites un commit local de votre nouvelle solution :

commis web project

 

Puis faites un push de votre branche vers Azure DevOps :

push web project

 

Vous devriez maintenant retrouver votre code sur Azure DevOps :

Web project on Azure DevOps

 

 

4ème étape – création d’une définition de build YAML

Maintenant que notre repo Git est initialisé avec un peu de contenu, nous arrivons à la partie qui nous intéresse le plus ici, la création d’une définition YAML de build.

 

Cliquez sur le bouton « Set up build » situé en haut à droite de l’écran pour commencer la configuration. Vous pouvez aussi passer par le menu « Pipelines » puis « Create your pipeline ».

Si vous le faites depuis le dépôt de code vous n’aurez pas à passer par l’étape de sélection de l’emplacement de vos sources.

 

Le processus complet ressemble à celui-ci :

start new pipeline

 

Remarque : Sous la liste des différents types de repo, un peu caché, se trouve le lien pour utiliser l’éditeur classique.

 

Après avoir choisi Azure Repos Git, vous devez sélectionner le repo :

select source repository

 

Si vous choisissez d’héberger votre code sur GitHub, vous aurez à vous connecter et à approuver la création d’une connexion de service permettant à Azure DevOps d’accéder à votre repo.

Cela se fait très bien et encore plus facilement si vous vous êtes connecté à Azure DevOps à l’aide de votre compte GitHub.

 

Choisissez le template adapté à votre projet. Si comme moi vous avez créé un projet ASP.NET Core, vous devrez cliquer sur « Show more », puis choisir « ASP.NET Core ».

slect AspNet Core template

 

Vous pouvez visualiser le template YAML créé pour vous, et le modifier si besoin. Par défaut, celui-ci se contente du minimum.

 

Cliquez sur « Save and run » afin d’enregistrer le fichier yml dans le repo Git et déclencher automatiquement l’exécution d’une build :

Save and run

 

Si tout va bien vous devriez rapidement voir le résultat positif de la compilation :

first run

 

Si vous revenez maintenant dans VS Code et que vous synchronisez votre branche locale avec le repo distant (pull), vous devriez voir apparaître le fichier “azure-pipelines.yml”.

Pipeline in VS code

 

Nous allons maintenant ajouter un projet pour faire les tests unitaires et exécuter ces tests dans notre pipeline de build.

 

Notez au passage l’instruction « trigger : – master » dans notre fichier yml. Cela veut dire qu’une build va être lancée automatiquement à chaque nouveau push sur la branche master. Il est possible de la même façon d’ajouter des filtres dans le trigger, ou de rendre l’exécution automatique lors de la création des pull-request.

 

Après avoir créé le projet de test, faites un commit local puis faites un push pour mettre à jour la branche distante. Une nouvelle build va automatiquement être exécutée. Cette fois, les deux projets sont compilés, mais pour l’instant aucun test n’est exécuté côté serveur.

Nous allons donc compléter notre définition de build avec une instruction “dotnet test” que nous pourrions réaliser soit en ligne de commande (via un step de type script), soit à l’aide d’une tâche proposée par Azure DevOps.

 

Vous pouvez réaliser cette modification directement sur le serveur en mode texte ou designer, ou bien depuis VS Code en mode texte uniquement.

 

Une nouvelle build va se déclencher et cette fois, les tests seront exécutés et un rapport sera automatiquement ajouté à la sortie de la build.

 

Un onglet supplémentaire apparaît alors, il s’agit de l’onglet « Tests » :

Pipeline with test

 

Il présente le résultat des tests et leur évolution au fil des exécutions.

Test summary

 

Remarque : Cette fonctionnalité n’est pas propre à Yaml. Il est tout à fait possible de faire exactement la même chose à l’aide des définitions classiques.

 

Et voilà, notre première définition de build en YAML est créée. Nous avons même mis en place de l’intégration continue. A chaque nouveau push dans notre repo, une build va se déclencher, y compris si un commit concerne le fichier azure-pipeline.yml. Les tests automatisés seront exécutés et nous aurons un retour quasi immédiat sur la qualité de notre travail.

 

 

Organiser les étapes

Afin de rendre l’exécution de notre build un peu plus lisible, nous allons utiliser quelques fonctionnalités offertes par Azure Pipelines, qui vont nous permettre d’organiser les étapes de notre pipeline.

Nous pouvons, comme pour les pipelines classiques, organiser nos étapes en plusieurs jobs, voire en plusieurs stages.

Pour rappel, pour cette dernière fonctionnalité, vous devez avoir activé la preview des pipelines multi-stages.

 

Tout d’abord, en utilisant les jobs, il est possible de scinder les tâches en deux étapes qui seront d’abord, le build, puis les tests :

 

Run with multiple jobs

 

C’est un usage assez classique qu’on retrouvera assez souvent.

 

A des fins de démonstration, allons encore un peu plus loin et utilisons cette fois les stages.

Nous ajoutons dans le fichier yaml, la définition de deux stages, un pour le build, l’autre pour le test :

 

Les deux stages sont visibles sur l’écran de synthèse des différents runs de notre définition de build :

Run with multiple stages

 

Dans le détail du run, les deux stages apparaissent de façon séquentielle. C’est le comportement par défaut lorsqu’aucune indication de dépendance n’est mentionnée.

stages summary

 

Et voilà un aperçu de ce à quoi peut ressembler une définition de build qui mêle les tâches, les jobs et les stages.

 

Vous pouvez composer ainsi votre workflow d’exécution de vos tâches. Vous pouvez bien-sûr paralléliser des jobs ou des stages, mettre des conditions d’exécution pour exécuter un job seulement si les autres sont en succès, ou au contraire en cas d’erreur.

 

Restez connectés !

En plus de faciliter la gestion par les développeurs et la possibilité de versionner les définitions, il est possible d’avoir des versions différentes selon les branches. C’est utile si vous devez gérer des montées de versions des outils, ou frameworks par exemple. Ou bien si vous devez intégrer des étapes qui dépendent de scripts qui ne sont pas encore présents dans le tronc commun de développement.

Nous n’avons vu ici qu’un aperçu des fonctionnalités offertes par les définitions de pipeline en YAML.

 

Pour plus d’information et connaître l’étendue des possibilités des définitions YAML, n’hésitez pas à consulter la documentation officielle Microsoft.

Dans un prochain article, j’aborderai le déploiement. Nous verrons alors comment il est possible de décrire en YAML un pipeline de release.

D’ici là, gardez un œil sur l’actualité d’Azure DevOps. Toutes les trois semaines, une nouvelle version de la plateforme est livrée par l’équipe et très souvent, vient enrichir l’expérience des pipelines en YAML.

Pour ce faire, vous pouvez consulter la roadmap présente sur la documentation Microsoft. Ou bien encore suivre le compte twitter @AzureDevOps.