Continuous integration
Maintenant qu'on a une banque de tests automatiques, on aimerait les utiliser pour assurer notre procédure de Continuous Integration.
Pour cela, il faudrait une plateforme de développement comme GitHub ou GitLab, qui va permettre l'automatisation des tâches.
Pour ce cours, nous allons utiliser une instance de Gitlab que je mets à votre disposition :
https://gitlab.mt.glassworks.tech
Vous pouvez vous créer un compte avec votre adresse autre que @hetic.eu (qui bloque les emails du serveur GitLab).
Merci d'utiliser votre vrai nom pour la création du compte pour que je puisse vous identifier plus facilement.
N'oubliez pas de charger votre clé SSH pour plus simplement faire les clones et pull et push.
Créer votre projet Gitlab
Connectez-vous au serveur Gitlab, créez votre premier projet :
Le projet devrait être en mode
Private.Désactivez l'option de créer une
README.md
Après avoir crée le projet, sur la page principale du projet, cliquez sur le bouton bleue "Code", et copiez le lien "https://...". Collez ce lien dans un fichier brouillon. Nous allons l'utiliser plus tard !
Créer un jeton d'accès
Sur Gitlab, naviguez dans "Settings -> Access Tokens". Ajoutez un nouveau token avec les droits suivante :
Role: "Maintainer"
read_repositorywrite_repository
Copiez le jeton généré. Attention, il n'est affiché qu'une seule fois ! Collez le jeton dans votre fichier brouillon. On va l'utiliser plus tard !
Configurer GIT dans votre DevContainer
Retournez à votre projet VSCode.
Dans le terminal tapez, en remplaçant les coordonnées :
Ceci établit votre identité pour toues les interactions avec GIT.
Préparer votre projet
Créez et sauvegardez votre projet :
Une fois seulement, nous allons dire à GIT où synchroniser notre projet :
Si vous vous êtes trompés de origin ou vous avez des erreurs concernant l'origin, on peut recommencer en faisant :
Modifications futures
Quand vous apportez des modifications à votre base de code, vous pouvez désormais faire le suivant :
Si jamais une version plus récente existe sur le serveur, il faut d'abord faire :
... afin de récupérer cette version du serveur, avant de faire git push
Dans le cas où, en récupérant une version du serveur, git rencontre une erreur style "vous avez de modifications locales", il y a deux options :
Gitlab Runner
Le processus de CI qu'on est en train de créer s'appelle autrement "Automated DevOps". Nous allons lancer les processus qui s'occupe automatiquement du build et test de notre base de code.
Pour ce faire, il faudrait lui donner des ressources d'exécution (CPU, RAM, stockage, etc).
On appelle une ressource d'exécution un Runner dans GitLab.
Qu'est-ce que c'est un Runner ?

Un Runner est un processus qui tourne sur un autre serveur ou instance.
Je vous ai déjà créé de Runners sur mon instance qui sont partagés sur touts la classe. Vous pouvez le voir en naviguant dans les réglages de votre projet sur Gitlab (Settings / CICD / Runners):

.gitlab-ci.yml
Gitlab va automatiquement lancer des processus d'intégration et/ou déploiement selon les instructions précisées dans le fichier .gitlab-ci.yml qui devrait se trouver à la racine de notre projet.
Alternativement, on pourrait naviguer dans le menu CI/CD de Gitlab, et dans le sous-menu Build → Pipeline Editor, pourrait modifier directement ce fichier.

Notez qu'avec chaque sauvegarde, on fait implicitement un commit à notre branche actuelle !
Collons le texte suivant dans l'éditeur :
Quand on sauvegarde, Gitlab va lancer un "Runner" (avec le tag general).
Quand le pipeline de Gitlab se lance, un Runner est activé pour chaque tâche. En vrai, un container Docker est créé, dans lequel tourne le script précisé sous script dans .gitlab-ci.yml.

Stages
Notre pipeline se compose de plusieurs étapes. Chaque étape doit compléter avant de procéder au suivant. Dans notre fichier, on a créé une seule étape test. On a attaché la tâche unit-testing-job à cette étape.
Le tag only
onlyVia le tag only, on a pu préciser exactement QUAND chaque tâche doit être exécutée. Ici, on précise que le pipeline doit exécuter s'il y a un commit sur la branche master, main ou production. Aussi, si un merge-request est créé ou mis à jour.
Cela veut dire que si on crée une branche lambda, le pipeline ne va s'exécuter tant que cette branche ne devient pas un merge-request.
Artéfacts
Un artéfact est un fichier sortant de notre tâche qui sera sauvegardé dans Git. Ici, on utilise les données sortantes de istanbul qui indique le code coverage de nos tests. Gitlab comprend ce format, et on pourrait donc voir dans les merge-requests les lignes touchées par les tests ou pas.
Testons en créant une branche, en effectuant une modification, et en créant un merge request :
Naviguer dans Gitlab. Vous verrez la branche sous Repository / Branches, et on peut créer un merge request.
Après avoir créé le merge-request, on voit que le pipeline a été créé. On attend qu'il soit terminé.

Une fois terminé, on aura un rapport sur la couverture de nos tests !
Si on regarde les modifications apportés par le merge request, on verra des petits traits verts qui indiquent si les tests ont bien couvert une ligne précise ou pas :

Surveiller l'exécution
On peut voir l'avancement de notre pipeline :

Et, pour chaque tâche, consulter le progrès ou les résultats :

Partout dans Gitlab, on peut aussi consulter le statut du pipeline :

Exercice : Est-ce que votre pipeline termine correctement ? Essayer de modifier vos codes sources pour ne plus faire fonctionner vos tests, et faire un commit. Qu'est-ce qui se passe ?
N'oubliez pas de corriger votre code après !
Ajouter une étape pour nos tests d'intégration
On va ajouter nos tests d'intégration.
Par contre, ses tests ont besoin d'une dépendance externe, notamment MariaDB. Comment faire ?
Grâce à Docker, on pourrait préciser MariaDB comme un service externe.
Ajoutez le suivant à votre .gitlab-ci.yml :
Quand on push notre modification, on voit qu'il y a 2 tâches dans notre pipeline maintenant :

Ouvrez la console de la tâche integration-testing-job. Vous verrez que MariaDB est chargé et utilisé pour exécuter nos tests !
Build notre image Docker finale
On est content de nos tests pour le moment. On aimerait maintenant construire une image Docker qu'on pourrait utiliser pour déployer en production.
Heureusement, Gitlab-CI pour le faire pour nous !
D'abord, on va ajouter un stage build qui va être exécuté seulement si le stage test aurait bien terminé.
Ensuite, on ajoute une nouvelle tâche à notre pipeline :
Regardez la partie script : vous vous souvenez que nous avons fait tout cela manuellement dans le chapitre K8s ? Nous sommes maintenant occupés à créer un script qui le fera automatiquement ! En plus, pas besoin d'un compte DockerHub, car Gitlab contient aussi son propre dépôt d'images Docker !
Remarquez un nouveau stage dans notre pipeline :

Vous allez remarquer dans la console que l'image Docker est construite en utilisant le Dockerfile.prod qu'on avait précisé dans le projet. Notamment, on compile le typescript, et on installe les node_modules pour production.
Ensuite, la tâche va envoyer l'image finale à notre "Container Registry" personnalisé sur Gitlab, dans Deploy → Container Registry :

Le Container Registry de Gitlab est comme Docker Hub, sauf qu'on peut gérer les images en interne et en privé !
e2e test avec notre image de production
Vous avez peut-être remarqué qu'on n'a pas encore intégré nos tests e2e. C'est fait exprès !
En fait, notre objectif est de lancer nos tests e2e contre notre image de production, pour être double sûr que l'image Docker fonctionne correctement. Nous sommes vraiment très proches aux conditions de déploiement !
Cette tâche est un peu plus compliquée à configurer :
Il faut lancer MariaDB comme avant
Il faut récupérer notre image qu'on vient de créer, et l'instancier en tant que
servicepour notre tâche (et lui dire de communiquer avec le service MariaDB).Ensuite, on lance notre test e2e, en lui disant d'envoyer ses requêtes à ce service
On commence par ajouter une autre étape e2e-test:
On va ajouter une variable globale, qui dit à Gitlab de laisser communiquer les services entre eux (pour que notre API puisse parler avec MariaDB) :
Ensuite, on ajoute une nouvelle tâche :
On voit encore une tache dans la pipeline :

La suite
Ça y est, on a configuré un pipeline CI qui permet au tech-lead de valider qu'une branche passe tous les tests possibles.
Maintenant, il pourrait décider plus tranquillement d'inclure la branche dans le main ou master, ou bien déployer l'image docker généré en production.
Le .gitlab-ci.yml complet
.gitlab-ci.yml completVous pouvez cloner le projet entier ici
Mis à jour