L'intégration continue avec Hudson

Romain Linsolas

Cet article est une description approfondie de l'outil d'Intégration Continue HUDSON.

- Titre : L'intégration continue avec Hudson

- Auteur : Romain Linsolas

- Parution : 6 avril 2008

- Mise à jour : 17 juin 2020

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. L'intégration continue

- I-A. Glossaire

- I-B. Principe

- I-C. Les outils

- II. Installation et configuration d'Hudson

- II-A. Préambule

- II-B. Installation

- II-C. Configuration

- III. Mon premier projet

- III-A. Mon projet avec Maven 2

- III-B. Mon projet avec Ant

- IV. Fonctionnalités principales

- IV-A. Indicateurs

- IV-A-1. Statut d'un projet

- IV-A-2. Santé d'un projet

- IV-A-3. Tendance d'un projet

- IV-B. Maître et esclaves

- IV-C. Matrice de configurations

- IV-D. Gestion des utilisateurs

- IV-E. Sécurité

- IV-F. Rapports de tests

- V. Plugins

- V-A. Les plugins

- V-B. Gestion des plugins

- V-C. Développement de plugins

- VI. Conclusion

- VI-A. Références

- VI-B. Remerciements

- VI-C. Informations complémentaires

I - L'intégration continue

I-A - Glossaire

Terme

Signification

Définition

SCM

Source Control Management

Système de gestion de versions, comme CVS, Subversion (SVN), ClearCase, etc.

IC

Intégration Continue

Voir le premier chapitre :)

build

Construire / compiler un projet.

builder

Résultat de la compilation d'un projet (un JAR ou un WAR par exemple).

I-B - Principe

L'Intégration Continue (" I.C. ") est le nom donné initialement par la communauté de l'Extreme Programming (" XP ") pour désigner la pratique de génie logicielle visant à accélérer la livraison des logiciels en réduisant le temps d'intégration.

Pour que l'Intégration Continue puisse se faire correctement, il faut tout d'abord partager les sources du projet via un serveur de Gestion de Contrôle des Sources (ou " SCM " pour Source Control Management) tel que CVS ou Subversion. Il faut également que les équipes de développements postent (committent) régulièrement les modifications apportées au code, de préférence plusieurs fois par jour. Enfin, il est nécessaire de disposer de tests unitaires qui seront exécutés par l'outil JUnit ou TestNG par exemple.

La présence des tests n'est en réalité pas obligatoire, mais elle est très fortement conseillée. Ils ont en effet pour tâche principale de vérifier que le code ne subit pas de régression, et que les fonctions implémentées réalisent correctement leurs tâches. Plusieurs types de tests existent (tests unitaires, fonctionnels, graphiques, de déploiement, etc.), chaque type ayant un rôle précis dans la vérification de l'application et de son code. Les tests étant un (très) vaste sujet, nous ne nous y étendrons pas davantage dans cet article

Des outils vont alors se charger de vérifier régulièrement les modifications sur le SCM afin d'assurer la non régression de l'application, en compilant l'ensemble du projet et en en exécutant les tests unitaires.

Globalement, les principaux intérêts de l'IC sont les suivants :

- Vérification fréquente du code, et de sa bonne compilation.

- Réalisation des tests unitaire et / ou fonctionnels, voire tests d'intégration.

- Mise à disposition éventuelle d'une version testable comportant les dernières modifications du code (on pourra ainsi faire déployer son WAR sur un serveur Tomcat tous les jours).

- Possibilité de créer des rapports périodiques exprimant la qualité du code, la couverture des tests, etc. Si le projet est configuré pour Maven, alors on pourra créer le site du projet qui contiendra l'ensemble de ces rapports.

Les deux premiers avantages de cette liste montrent que l'IC permet de détecter quasi-immédiatement la présence d'un problème dans le code... et donc d'y apporter une solution instantanément !

I-C - Les outils

Il existe aujourd'hui de nombreux outils d'intégration continue. Nous n'allons pas aller dans le détail de chacun d'eux, mais voici une liste (loin d'être exhaustive) des principaux outils existants dans ce domaine :

- Anthill Pro.

- Atlassian Bamboo.

- Build Forge.

- Cruise Control : l'un des outils d'IC les plus anciens et plutôt populaire.

- Apache Continuum : l'outil " officiel " de la communauté Maven.

- Hudson : l'un des tout derniers, qui fait beaucoup parler de lui. Pour preuve, cet article lui est entièrement consacré !

- Luntbuild (et Luntbuild pro).

- JetBrains TeamCity.

- etc.

Une page faisant un comparatif assez complet entre de nombreux outils d'IC est disponible ici.

II - Installation et configuration d'Hudson

II-A - Préambule

Hudson est un serveur d'Intégration Continue très en vogue actuellement. Sa simplicité, comme nous allons le voir dans les chapitres suivants, en fait un outil très apprécié. La version d'Hudson présentée dans cet article est la 1.200, la dernière disponible lors de la publication de cet article est la 1.206 (le 9 Avril 2008).

La license d'Hudson est à la fois basée sur la license Creative Commons et sur la license MIT. Concrètement, son utilisation est libre, que ce soit pour une utilisation dans un cadre personnel ou dans un cadre professionnel.

II-B - Installation

Pour faire fonctionner Hudson, la seule contrainte est de disposer d'une JVM sur le serveur (Java 5 ou supérieur est requis). La première étape, bien sûr, est de télécharger Hudson sur le site officiel de l'application. Une fois le fichier WAR téléchargé, il suffit de lancer la commande suivante pour démarrer le serveur Hudson : java -jar hudson.war.

On privilégiera cependant l'installation du package hudson.war dans un containeur, tel que le serveur Apache Tomcat. Il est même possible de tester Hudson sans le télécharger, en utilisant la version JNPL disponible ici !

Hudson va loger tous les fichiers nécessaires à son fonctionnement dans son espace de travail (le " workspace "). Ce répertoire se définit via la variable système HUDSON_HOME. Il contiendra tous les fichiers XML de configuration, ainsi que tous les projets - et leurs fichiers - qui seront créés avec cet outil. Ainsi, la mise à jour d'Hudson se réalise très aisément, en ne mettant à jour que le fichier WAR hébergé par Tomcat, aucun fichier de " travail " n'étant perdu.

En se rendant à l'adresse locale http://localhost:8080/hudson (ou http://localhost:8080) on arrive sur la page d'accueil du serveur d'Hudson. L'interface y est pour le moment très épurée :

On notera la présence d'une boite de recherche située dans l'entête de toutes les pages d'Hudson. Cette fonction de recherche permet surtout de se déplacer rapidement vers une page précise d'Hudson, d'un projet, etc. Voir la page ici (en anglais) pour plus de détails...

II-C - Configuration

Contrairement à certains autres outils d'IC, Hudson ne nécessite l'écriture ou la modification d'aucun fichier XML. Toute la configuration (qu'elle soit générale ou spécifique à un projet) se fait directement depuis l'interface en ligne d'Hudson. Sur la page principale, le lien " Gérer Hudson " permet d'accéder aux fonctions suivantes :

- Configuration système : configuration générale d'Hudson : répertoire d'installation des JDK, de Maven, configuration du SCM, gestion de la sécurité, etc.

- Rechargement la configuration à partir du disque : permet de recharger la configuration contenue dans les fichiers XML se trouvant sur le disque dur du serveur. Utile lorsque l'on s'amuse à modifier manuellement les fichiers de configuration.

- Gérer les plugins : gestionnaire des plugins d'Hudson.

- Informations système : informations sur la configuration système du serveur.

- Log système : logs d'Hudson.

- Console de script : exécution de scripts pour l'administration.

- Gérer les machines esclaves (option disponible seulement si des machines esclaves sont définies) : permet de vérifier l'état des machines esclaves.

- Se préparer à la fermeture : commande utilisée pour préparer Hudson à son arrêt, de façon propre. A employer lorsqu'il s'agit de mettre à jour la version d'Hudson ou tout simplement pour stopper le serveur Tomcat.

Jetons maintenant un oeil attentif au panneau de configuration système d'Hudson. Voici quelques paramètres intéressants :

- Nombre de lanceurs : nombre maximal d'exécutions concurrentes qu'Hudson peut lancer. Autrement dit, ce paramètre définit combien de compilations simultanées peuvent être lancées par le serveur d'IC.

- Activer la sécurité : permet de gérer la sécurité sur Hudson, de façon à en limiter son accès. Nous y reviendrons plus tard.

- JDKs : liste des JDK installés sur le serveur.

- Ant : liste des versions de Ant installés sur le serveur.

- Maven : liste des Maven installés sur le serveur.

- Notification par email : paramètres de configuration pour l'envoi des emails.

Ces paramètres sont importants, car ils seront utilisés pour nos projets Hudson. Nous allons d'ailleurs nous occuper maintenant de créer notre premier projet.

III - Mon premier projet

III-A - Mon projet avec Maven 2

Nous allons créer notre premier projet. Considérons que nous disposons d'un projet basé sur Maven 2. Nous choisissons donc l'option " Construire un projet Maven 2 " parmi les possibilités offertes par Hudson lorsque l'on crée un nouveau job.

Les autres options sont les suivantes :

- Construire un projet free-style : créer un projet en choisissant sa propre configuration. Utile si l'on veut gérer un projet basé sur Ant ou si l'on désire exécuter des lignes de commandes batch Windows.

- Construire un projet multi-configuration : créer un projet pouvant disposer d'une configuration multiple (voir la " matrice de configuration " dans le chapitre sur les fonctionnalités avancées).

- Contrôler un job externe : ce type de projet permet de suivre l'exécution d'un process exécuté hors d'Hudson, éventuellement sur une machine distante.

- Copier un job existant : créer un nouveau projet à partir d'un projet déjà existant dans Hudson.

Sur cet écran de configuration, voici les options principales à paramétrer :

- Description : la description du projet !

- Supprimer les anciens builds : indique si Hudson doit supprimer les anciens builds de ce projet, afin de ne pas encombrer le serveur de fichiers. On peut paramétrer Hudson pour ne garder qu'un nombre limité de builds ou alors pour ne les conserver que pendant une période donnée... Il faut toutefois noter qu'Hudson ne se base que sur les builds conservés par le serveur pour définir les statistiques et l'historique du projet (temps de construction, résultats des tests, etc.).

- Désactiver le build : permet de désactiver le projet sans le supprimer.

- Gestion du Code Source : configuration du SCM, qui permet à Hudson d'aller récupérer les fichiers sources sur CVS ou Subversion par exemple. D'autres systèmes de SCM sont accessibles grâce à l'ajout de plugins.

- Scruter l'outil de gestion de version : une option permettant d'indiquer à Hudson d'aller vérifier périodiquement l'existence de fichiers modifiés sur le SCM pour lancer le build. Autrement dit, cette option permet à Hudson de ne lancer un build qu'en cas de modification des sources sur le serveur SCM.

- Builder périodiquement : force Hudson à faire des builds à intervalles réguliers, qu'il y ait des modifications sur le SCM ou non. On privilégiera toutefois l'option précédente, en fixant un intervalle de temps plus long pour gérer les nightly builds, ces builds qui prennent beaucoup de temps (car on va réaliser un maximum de tests, créer le site du projet contenant les rapports, etc.) et qui sont ainsi généralement lancés la nuit. Il est en effet inutile de démarrer un build si aucune modification du code n'a été faite depuis le précédent build...

- Goals : indique quel(s) goal(s) Maven 2 doivent être exécutés lors du build. Un bon choix serait par exemple " clean install ".

- Email notification : option permettant de dire à Hudson s'il faut envoyer des emails ou non à la fin d'un build lorsque celui-ci échoue, redevient correct (c'est-à-dire lors du premier build réussi après un échec) ou est instable (c'est-à-dire que certains tests ont échoué). Il est aussi possible de notifier, lors d'un échec, toutes les dernières personnes ayant mis à jour le code source sur le SCM depuis le dernier build réussi. Les développeurs sont ainsi informés automatiquement qu'un commit récent a cassé la compilation du code.

- Actions à la suite du build : actions à réaliser par Hudson une fois le build terminé. Il peut s'agir de lancer un autre projet, ou de déployer l'artifact créé sur un repository Maven.

On notera la présence de l'icône à proximité de la plupart des options, offrant une explication plus approfondie de l'option.

Comme on peut le constater, la création d'un projet Maven 2 est d'une grande simplicité avec Hudson : il suffit pratiquement de lui indiquer où trouver le pom.xml du projet sur le SCM pour qu'il se débrouille tout seul !

Une fois le projet créé, Hudson va nous proposer de lancer le premier build manuellement. On verra alors l'exécution d'un build apparaître dans l' " Historique des builds " d'Hudson

A noter qu'il est possible de s'abonner aux flux RSS pour chaque projet, comme le montre la capture précédente. Il existe un flux RSS regroupant tous les builds, ainsi qu'un autre flux se limitant aux builds en échec.

Une autre option intéressante est la possibilité de rassembler plusieurs projets au sein d'un même groupe pour plus de clarté, chaque groupe étant alors présenté dans un onglet sur la page d'accueil d'Hudson (l'ajout se fait en appuyant sur le dernier onglet marqué d'un " + ") :

Lors de la première lecture du pom.xml par Hudson, ce dernier va déterminer les éventuels sous-modules du projet. Lors de la construction d'un projet par Hudson, il est alors possible de suivre avec précision l'avancée du travail :

Lorsque l'on visualise un projet, nous pouvons voir sur la partie gauche de l'interface d'Hudson, une série d'options ou de commandes :

- Changements : liste des dernières modifications trouvées sur le SCM depuis le précédent build. Une sorte de changelog.

- Espace de travail : accès à l'espace de travail du projet, celui utilisé par Hudson. On peut y voir l'ensemble des fichiers sur lequel Hudson travaille, et les récupérer (une option utile permet de récupérer tous les fichiers sous forme de ZIP).

- Lancer un build : lance un build manuel sur ce projet.

- Supprimer ce projet : supprime définitivement ce projet d'Hudson. Il est possible, via la configuration du projet, de désactiver le projet, sans le supprimer.

- Configurer : permet de configurer ce projet.

Lorsque l'on visualise un build précis d'un projet, d'autres options sont proposées :

- Sortie console : la sortie console permet de voir ce que les logs des builds affichent. Il existe pour cela deux types de sortie console : la version standard et la version brute. L'avantage du premier est qu'il est possible de suivre en temps réel l'écriture des logs lorsqu'un build est en cours.

- Tagguer ce build : fonctionnalité pour tagguer le build en cours.

- Surveiller un process Maven : permet d'obtenir des informations précises sur le processus Maven en cours, comme les propriétés systèmes, les variables d'environnement, etc.

Une dernière option est disponible pour les projets Maven déjà exécutés : Mojos exécutés. On y voit la liste de tous les plugins Maven qui ont été lancés par le build d'Hudson, le goal utilisé, ainsi que leur durée d'exécution :

III-B - Mon projet avec Ant

Si le projet que vous désirez intégrer à Hudson est géré par Ant et non par Maven, il suffit de créer un nouveau " projet free-style " et de définir les tâches Ant à appeler, comme le montre la capture suivante :

La gestion du projet une fois celui-ci créé reste la même que pour un projet Maven...

IV - Fonctionnalités principales

Nous allons maintenant voir de plus près quelques fonctionnalités intéressantes proposées par Hudson.

IV-A - Indicateurs

IV-A-1 - Statut d'un projet

Il existe dans Hudson de multiples indicateurs permettant d'obtenir très rapidement des informations précises sur un projet. Par exemple, sur la page principale d'Hudson (ainsi que la page listant les sous modules d'un projet) chaque élément sera précédé par une icône indiquant son état. Le tableau ci-dessous liste les états possibles (si cette icône clignote, cela signifie que le projet est actuellement en cours de construction) :

Aucun build n'a jamais été créé pour ce projet, ou alors ce dernier est désactivé.

Le précédent build s'est terminé correctement.

Le précédent build était instable (des tests ont échoué).

Le précédent build a échoué (généralement due à une erreur de compilation).

IV-A-2 - Santé d'un projet

La " santé " d'un projet correspond au pourcentage de builds récents qui ont réussi. Plus ce pourcentage est élevé, meilleure est la santé du projet. Le tableau ci-dessous montre les différents échelons possibles de la " santé " d'un projet :

0% - 20%

20% - 40%

40% - 60%

60% - 80%

80% - 100%

En plaçant le curseur de la souris sur l'icône de santé, nous obtenons une information plus précise à son sujet :

IV-A-3 - Tendance d'un projet

La tendance d'un projet montre l'historique de la durée des builds. Ce graphique distingue également les builds en échec (là où la couleur est rouge) des builds réussis (la couleur est bleue sur le graphique) :

IV-B - Maître et esclaves

Hudson nous permet d'ajouter une liste de machines " esclaves " pour le serveur actuel, ce dernier étant alors considéré comme le " maître ". L'intérêt de cette fonctionnalité est de pouvoir exécuter des jobs sur des machines autres que le serveur, et donc d'augmenter le nombre de jobs concurrents possibles. Cela devient particulièrement intéressant dès lors que l'on utilise la matrice de configuration (voir chapitre suivant).

IV-C - Matrice de configurations

Le principe de la matrice de configurations est d'autoriser l'exécution d'un projet selon différentes configurations. Il est ainsi possible de construire le même projet avec différentes versions du JDK, pour tester la compatibilité du projet avec Java 1.4, Java 5, Java 6... Ce type de projet Hudson nous offre également la possibilité de réaliser des tests sur différentes bases de données, par exemple MySQL, PostgreSQL, Oracle, SQL Server... Cela correspond au concept des Axes, chaque axe étant une valeur précise pour un paramètre donné. Dans notre exemple de base de données, nous avons un axe database qui peut prendre les valeurs mysql, postgresql, oracle ou encore sqlserver.

Hudson va réaliser un build par combinaison possible. Si nous définissons 3 versions de Java à tester et 4 types de bases de données, Hudson aura donc besoin de réaliser 12 builds consécutifs pour créer la matrice de configurations. Ainsi, plus on a de paramètres, plus on couvrira de configurations possibles, mais en contrepartie, Hudson aura beaucoup plus de travail à fournir ! On appréciera ici particulièrement le fait de disposer de machines esclaves !

IV-D - Gestion des utilisateurs

La liste des utilisateurs est automatiquement mise à jour par Hudson via les informations récupérées sur le SCM. Lorsqu'un nouvel utilisateur commite un fichier sur le SCM, alors Hudson l'ajoutera lors du prochain build parmi la liste de ces utilisateurs. On peut ensuite configurer chaque utilisateur pour lui définir son adresse email. Ces informations seront utilisées par Hudson pour transmettre par email les rapports d'échec de builds. Ces utilisateurs peuvent également être utilisés pour définir les accès au serveur Hudson, comme nous allons le voir dans le chapitre suivant.

IV-E - Sécurité

La gestion de la sécurité permet de limiter l'accès, ou les opérations, pour un certain type d'utilisateur d'Hudson. Par défaut, celle-ci n'est pas activée, et par conséquent, toute personne peut se logguer sur Hudson et faire ce qui lui plaît : ajouter des projets, les configurer, les supprimer, lancer des builds manuels, etc.

La sécurité se gère au niveau de la configuration système d'Hudson, en sélectionnant l'option " Activer la sécurité " :

Trois options sont proposées pour gérer la liste des utilisateurs :

- Déléguer cela au containeur servlets, par exemple Tomcat.

- Utiliser la liste des utilisateurs d'Hudson (celle présentée au chapitre précédent).

- Utiliser un annuaire LDAP.

Hudson propose plusieurs façons de spécifier les droits des utilisateurs :

- Les utilisateurs loggués ont le droit de tout faire : autrement dit, un utilisateur ayant les droits d'accès à Hudson pourra faire ce qu'il y veut.

- N'importe qui peut tout faire : il s'agit de la même option que la précédente, à ceci près qu'aucune authentification n'est demandée. Cette option, sélectionnée par défaut, est à éviter si Hudson est accessible par un réseau externe (comme Internet).

- Mode legacy : dans ce mode, seul les utilisateurs admin sont autorisés à réaliser des actions sur les projets. Tous les autres utilisateurs ont un accès en lecture seule.

- Sécurité basée sur une matrice : grâce à ce mode, on peut attribuer des droits d'accès plus précis à chaque groupe d'utilisateurs :

IV-F - Rapports de tests

Hudson récupère automatiquement les informations liées à l'exécution des tests lorsqu'il construit un projet. A l'aide de ces graphiques, il est possible de voir l'évolution de l'exécution - et de la réussite - des tests au cours des builds du projet.

En cliquant sur ce graphique, la liste complète des tests - réussis et échoués - s'affiche, avec le détail de leur exécution.

V - Plugins

V-A - Les plugins

Hudson dispose de la possibilité d'étendre ses capacités grâce à l'ajout de plugins. Certains plugins vont ajouter le support d'un système particulier, comme par exemple le support des SCM ClearCase, Mercurial, Perforce, etc. D'autres vont offrir un support pour de nouveaux rapports. Nous pouvons ainsi disposer de rapports Clover, Cobertura, Crap4J, FindBugs, NUnit, etc. lors de la construction des projets.

Certains plugins vont également permettre de connecter Hudson à des systèmes externes, comme Jira, Trac, Google Calendar, etc.

La liste (non exhaustive, mais assez complète) des plugins disponibles pour Hudson est visible ici.

V-B - Gestion des plugins

Sur la page d'administration d'Hudson, une option est destinée à la configuration des plugins installés sur le serveur Hudson. On retrouvera sur cette page la liste des plugins installés, ainsi qu'un lien pour ajouter un nouveau plugin :

L'ajout d'un plugin se fait donc simplement en indiquant où trouver le fichier du plugin en question sur son disque dur (fichier à l'extension hpi). Celui-ci sera alors installé dans l'espace de travail d'Hudson (dans le répertoire HUDSON_HOME/plugins). La mise à jour d'Hudson sur Tomcat n'impactera donc pas l'installation - et la configuration - des plugins déjà présents.

Il est maintenant nécessaire de stopper puis de redémarrer Hudson pour que le plugin soit pris en compte (pensez à utiliser l'option " Préparation à la fermeture " !). Chaque plugin se configure d'une façon particulière. Par exemple, certains ajouterons une nouvelle option dans la configuration générale d'Hudson, d'autres proposeront un nouveau rapport lors de la construction d'un projet... Nous laisserons donc le soin de documenter ces informations à l'équipe de développement de ces plugins !

Il existe également des plugins pour différents IDE - Eclipse, NetBeans, IntelliJ - offrant une vue rapide de l'état des projets Hudson au sein même de l'IDE. La capture suivante illustre ceci pour la plateforme Eclipse :

V-C - Développement de plugins

On peut développer son propre plugin pour l'intégrer à Hudson. Une page indique tout ce qu'il faut savoir pour créer son propre plugin. Nous n'entrerons pas plus dans le détail du développement des plugins dans cet article, le sujet étant assez vaste !

VI - Conclusion

L'intérêt principal d'Hudson aujourd'hui est sa simplicité : simplicité d'installation, de configuration mais aussi d'utilisation. Ceci fait d'Hudson un outil idéal pour disposer d'un processus d'Intégration Continue rapidement exploitable, y compris sur des projets de petite taille.

Le projet Hudson, malgré une équipe restreinte de développeurs, reste néanmoins très actif (on le voit à la courbe de nombre de lignes de code ci-dessous) : nous en sommes aujourd'hui - début avril - à la version 1.202, alors que nous n'étions qu'à la version 1.165 au début 2008 !

VI-A - Références

Les sites présentés ici sont en anglais :

- Site officiel d'Hudson : https://hudson.dev.java.net

- Changelogs des versions: https://hudson.dev.java.net/changelog.html

- Wiki : http://hudson.gotdns.com/wiki/display/HUDSON/Use+Hudson

- http://en.wikipedia.org/wiki/Continuous_integration

- http://www.martinfowler.com/articles/continuousIntegration.html

VI-B - Remerciements

- Eric Lefèvre pour ses conseils.

- Pour la relecture: cdeniaud, David Gimelle et mon papa :)

- A l'équipe d'Hudson pour ce superbe outil, bien entendu !

VI-C - Informations complémentaires

- Version actuelle d'Hudson : 1.206.

- Version utilisée lors de la rédaction de cet article : 1.200.

- SCM supportés par Hudson:

- Nativement: CVS et Subversion.

- Grâce à l'ajout d'un plugin : Perforce, ClearCase, Mercurial et Acurev, StarTeam.