Démonstrateur CI
Ce projet a pour but de démontrer une chaine d'intégration, de la compilation à la livraison d'un artefact sur un dépôt d'archives.
Les décisions prises concernant la gestion des branches, des merges, des déclencheurs d'action et plus généralement l'intégration continue sur ce projet d'exemple, illustre les possibilités que gitlab nous offre. Il convient de l'adapter en fonction des contraintes de chaque projet.
Le projet utilisé pour démontrer la chaîne d'intégration continue, est un projet Java (maven, multi-module), volontairement simple. Il utilise des technologies standard et répandues :
- Maven pour la gestion des dépendances et du cycle de vie du projet (compilation, tests unitaires, packaging)
- Springboot pour le framework de développement
- Junit pour l'exécution des tests unitaires
Produit et stratégie d'intégration et de déploiement
Ce projet Gitlab vise à créer un produit exposant une interface web, qui affiche l'heure courante et la version du produit.
La stratégie de développement, d'intégration et de déploiement choisie sur ce projet est la suivante :
- Au quotidien : Contrôle de la compilation du code
- Régulièrement (1 fois par jour) : Contrôle de la qualimétrie (obsolescence, couverture de code, sonarqube)
- Dès qu'on a un ensemble fonctionnel cohérent :
- Envoi des livrables sur les dépôts de gitlab (jar, image Docker)
- Génération de rapport sur la sécurité et l'obsolescence des composants
- Déploiement automatique sur un hébergement externe
Git flow (stratégie d'utilisation de git)
La stratégie d'utilisation de git découle de l'organisation de l'équipe produit, décrite ci-dessus.
Le flow
présenté ici est inspiré du gitlab-flow
: https://docs.gitlab.com/ee/topics/gitlab_flow.html.
Ces décisions ne sont partagées qu'à titre d'exemple et ne constitue pas un modèle figé à appliquer pour tout projet.
Le développement au quotidien
Sur ce projet, il n'existe que deux types de branches :
- les branches
feature-*
, sur lesquelles les développeurs travaillent au quotidien - la branche
master
, qui accueille les développement une fois ceux-ci terminés
Lors des développements des fonctionnalités et des correctifs, les travaux sont faits sur des branches de fonctionnalités, nommées feature-*
.
A chaque fois qu'un commit est poussé sur gitlab, la tâche de compilation est lancée.
Pour partager son travail, le développeur crée une Merge Request
sur gitlab, pour demander à ce que son code soit revu et mergé sur la branche master
.
Lors de la création de la Merge Request
et pour chaque modification de la branche source (feature-*
) et de la branche cible (master
), un pipeline est lancé.
Ce pipeline lance les tâches de compilation et de tests unitaires sur la version cible du code.
Le schéma ci-dessous illustre le fonctionnement de l'intégration continue au quotidien.
La qualimétrie à intervalle régulier
Régulièrement, pour contrôler la qualité du code, on lance la tâche maven site
, qui gènère un ensemble de rapports :
- rapport d'obsolescence du code
- rapport de vulnerabilités des dépendances
- rapport de couverture des tests *...
Ce contrôle est planifié via les scheduled pipelines
: https://gitlab-forge.din.developpement-durable.gouv.fr/help/ci/pipelines/schedules
Il est effectué sur la branche master
et la dernière version des rapports est publiée sur les "gitlab-pages".
Le schéma ci-dessous illustre le fonctionnement de la qualimétrie dans le contexte de l'intégration continue.
Le dernier rapport pour ce projet est visible à l'URL suivante : https://snum.gitlab-pages.din.developpement-durable.gouv.fr/dam/archi/ci-maven-demo/
Les rapports précédents sont exportés sous la forme d'artéfacts et peuvent être consultés via la liste des pipelines, dans le menu CI/CD > Pipelines > Jobs
.
Publication des livrables
Une fois les développements prêts à être déployés, un tag
est créé sur le dernier commit de la branche master
.
La création de ce tag
, lance un pipeline, qui contrôle la qualité du code, puis crée et publie deux livrables :
- un jar, publié sur le dépôt d'archives de gitlab
- une image docker, contenant le jar créé précedémment
Le schéma ci-dessous illustre le fonctionnement de la publication.
Déploiement de l'application
Suite à la création du tag, l'application est automatiquement déployée. Dans l'exemple présent, il n'existe qu'un environnement sur lequel l'application est déployée automatiquement. En pratique, le déploiement peut se faire sur des environnements différents, à des fréquences différentes, avec des déclencheurs différents.
L'environnement sur lequel est déployé une application, n'est pas lié à Gitlab : on peut citer l'hébergement sec, eco ou le C3 comme des cibles potentielles.
Le schéma ci-dessous illustre un exemple de flux de déploiement.
Chaîne d'intégration continue
La chaîne d'intégration du projet est divisée en plusieurs phases (stages
), dans lesquelles sont executées différentes tâches (jobs
) :
Phase | Tâche | Description |
---|---|---|
build | ||
compile | compilation du projet | |
test | ||
unit-test | lancement des tests unitaires et création des rapports Jacoco | |
analysis | ||
cobertura-convert | conversion du rapport de couverture Jacoco en rapport Cobertura, interprétable par Gitlab | |
site | construction du site maven (et de ses divers rapports) | |
sonarqube-check | lancement de l'analyse de code sur sonarqube | |
package | ||
build-artefact | construction du jar de l'application | |
publish | ||
pages | envoi des rapports sur gitlab pages | |
publish-artefact | envoi de l'artefact sur un dépôt d'archive | |
publish-docker-image | création et publication d'une image docker permettant d'éxecuter le projet | |
deploy | ||
deploy-services | déploiement du service (spécifique Kubernetes) | |
deploy-app | déploiement de l'application |
~ Fin ~