Accueil > Non classé > Hudson : retour d’expérience et conseils pratiques

Hudson : retour d’expérience et conseils pratiques

butlerPour ceux qui pratiquent l’Extreme Programming ou l’Agilité, l’intégration continue est devenue incontournable.

A titre de rappel, l’intégration continue est une pratique permettant le suivi de la qualité d’un projet en compilant régulièrement ses sources et en évaluant ses métriques (nombre de tests en échec ou nombre de warnings checktyle par exemple). La mise en place de cette pratique est assurée par des outils tels que Hudson, Continuum ou Cruisecontrol.


Un moustachu qui vous veut du bien…

Dans le cadre de cet article, je vais vous présenter Hudson et partager avec vous un peu de l’expérience que j’ai de cet outil.hudson5
En plus des fonctionnalités que l’on s’attend à trouver comme l’interfaçage avec un SCM (Subversion ou CVS), le lancement automatisé de tâches Maven et Ant ou la notification par mail des régressions, Hudson nous permet :

  • la publication de la javadoc du projet,
  • l’installation de plugins,
  • l’exécution de commandes Windows ou de scripts shell,
  • de suivre l’évolution du nombre de tests unitaires en échec,
  • de suivre l’évolution du temps mis par le projet pour se compiler, s’auto-tester et éventuellement se packager.

et bien plus encore grâce à la multitude de plugins disponibles.

L’interêt de cet outil par rapport à la plupart de ses concurrents est sa facilité d’installation et d’administration ainsi que son nombre toujours grandissant de fonctionnalités assurées par ses plugins. Évidement, le développement de ces plugins est possible à l’aide des indications que vous trouverez ici.

Des plugins? Oui, mais lesquels?warning

Tous vous les présenter ne serait pas forcément utile. Je vais me contenter d’aborder ceux que je vous recommande :

  • Static code analysis Plugin : indispensable pour l’installation des 3 plugins suivants.
  • Warnings Plugin : pour parser et analyser le flux généré par la compilation du java afin de comptabiliser le nombre et la nature des warnings renvoyés par le compilateur.
  • Checkstyle Plugin : pour parser et suivre de la même façon que le plugin précédent les warnings checkstyle.checkstyle-task Évidement, pour être efficace, l’une de vos tâches Maven ou Ant doit exécuter l’analyse checkstyle générant un rapport sous forme de fichier xml.
  • Task Scanner Plugin : pour détecter et suivre le nombre, l’emplacement et la nature des tâches ouvertes (TODO par exemple) dans vos fichiers sources. Contrairement à Eclipse qui ne peut détecter les FIXME que vous risquez d’oublier,(édition suite à la remarque de Pierre-Antoine Grégoire) Ce plugin vous permet de les repérer et de les afficher avec un niveau de priorité supérieur aux TODO (selon votre façon de le configurer, bien sûr).
  • Batch Task Plugin : parfois, il est nécessaire d’exécuter des commandes ou des scripts manuellement. Par exemple, il peut être intéressant d’appeler une tâche Maven de livraison ou d’exécuter une commande robocopy pour déposer un livrable sur une machine distante. Ce plugin nous permet d’exécuter ce type de commande en marge de la tâche principale de compilation et de contrôle du projet.
  • Cobertura Plugin : dans l’éventualité où vous évaluez la couverture de tests de votre projet avec Cobertura, ce plugin vous permettra de la publier et d’en suivre l’évolution. Cependant, pour avoir des résultats cohérents, je vous recommande de cocher l’option “Consider only stable builds” sur la page de configuration du projet.test
  • Subversion Release Manager : par défaut, Hudson n’effectue les tâche pour lesquels vous le configurez qu’en se basant sur la dernière version des sources disponible sur votre SCM préféré. Cependant, il arrive qu’on ait besoin d’exécuter une tâche de compilation et de packaging à partir d’une version antérieure. Dans ce cas, ce plugin vous sauvera la vie en vous permettant de choisir la révision SVN dont vous avez besoin.
  • Change Log History Plugin : une des bonnes pratiques à appliquer à l’intégration continue est la limitation du nombre d’exécutions conservées par l’outil (que nous appellerons builds par la suite). De plus, il arrive que des builds doivent être supprimés manuellement parce qu’ils ont été interrompus trop tôt et qu’ils faussent le suivi du projet. Dans ces conditions, ce plugin permet de rattacher la log SVN des builds supprimés aux builds restants. Par exemple, imaginons que le build #X comporte une log SVN conséquente (ou du moins pertinente même si en principe toutes les logs devraient l’être). Ce build a été interrompu suite à une mauvaise manipulation ou une mauvaise configuration (donc a priori, pour de mauvaises raisons). Par la suite, le build #X+1 qui est relancé manuellement juste après l’interruption du build #X ne contient que peu de log SVN voir aucune si aucun commit n’a été effectué entre temps. Au final, on a un build #X+1 associé à un état du projet (quasiment celui du build #X) sans avoir la log SVN correspondante. A l’aide de ce plugin, il suffit de supprimer le build #X pour rajouter sa log SVN au build #X+1 et aspirer à un peu plus de clarté.

Quelques conseils pratiques:

En plus des bonnes pratiques préconisées par Martin Fowler que vous trouverez ici, je vous recommande les astuces suivantes dans le cadre de l’utilisation de Hudson :

  • Définir un répertoire de travail spécifique (BuildArea par exemple) à la racine de votre projet (au lieu de la racine elle-même par défaut). Ceci vous permettra de placer et de manipuler d’éventuels fichiers indépendants de ceux qui sont chargés du SCM. Par exemple, si vous n’utilisez pas Maven et sa gestion de profils et si vos scripts Ant ne prévoient pas d’utiliser des fichiers de configurations spécifiques à l’intégration continue (parfois l’existant ne s’y prête pas), alors vous souhaiterez définir un répertoire conf à la racine du projet contenant cette configuration spécifique. Il suffit alors de définir une étape dans votre configuration de projet pour copier ces fichiers et de les coller à l’emplacement adéquat du BuildArea. Cette étape devra évidemment se positionner avant l’exécution des tâches Ant (soit une commande à définir entre le chargement des sources et le lancement des tâches de compilation et de contrôle).
  • Comme il a été déjà mentionné plus haut, une bonne pratique très courante en intégration continue consiste à limiter le nombre de builds conservés afin d’éviter la surcharge du disque dur de votre machine. Avec Hudson, il est effectivement possible de choisir un mode de conservation par nombre de jours ou par nombre de builds.
  • Dans le cas où un des builds est utilisé pour créer un livrable, n’hésitez pas à lui ajouter une description indiquant le numéro de version de la release. Hudson conserve pour chaque build des informations telles que le numéro de révision SVN, le jour et l’heure du packaging et la log SVN. Il vous sera d’autant plus facile de retrouver ces informations concernant une livraison si la tâche de packaging associée a été mise en évidence dans l’historique des builds.
  • Compte tenu du conseil précédent, il peut être intéressant de verrouiller les builds à l’origine des versions majeures de votre application (c’est à dire, empêcher leur suppression). Vous pourrez ainsi constater l’évolution des différentes métriques sur une grande échelle de temps malgré la limitation de la durée de conservation des builds.
  • Encore une fois, si un des builds est à l’origine d’une release, vous pouvez définir une tâche manuelle exécutée indépendamment de la tâche de packaging à l’aide de Batch Task Plugin. Vous pouvez alors en profiter pour copier les livrables dans le répertoire release du build associé. Ce qui permettra par la suite de récupérer ces livrables par téléchargement à partir de la page de projet d’Hudson (si il s’agit du dernier build) ou de la page du build lui-même. Les commandes pour copier les archives devraient ressembler à ceci:
    
    
    1
    2
    cd %WORKSPACE%
    copy "..\BuildArea\MyProject\target\*.ear" "..\..\..\jobs\%JOB_NAME%\builds\%BUILD_ID%\archive\MyProject\target\" /v /y

Et pourquoi pas le PL/SQL tant qu’on y est…

En rusant un peu, il est possible d’utiliser Hudson pour faire de l’intégration continue de scripts PL/SQL. En fait, l’idée est de charger et déployer ces scripts à l’aide d’une tâche Maven ou Ant sur un client Oracle et d’en intercepter et parser soi-même la sortie. Pour y arriver, nous allons écrire la tâche Ant suivante :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<target name="compile.sources" unless="disable.sql.compile.source">
    <exec executable="sqlplus"
       failonerror="true"
       dir="${build.dir}/${project.name}/${db.dir.name}">
            <arg value="/nolog"/>
            <arg value="@go_sources.sql"/>
    </exec>

    <loadfile property="sqlplus.log.file"
       srcFile="${build.dir}/${project.name}/${db.dir.name}/${log.dir.name}/${log.file}"
       failonerror="true"/>

    <condition property="has.sql.errors">
        <or>
            <contains string="${sqlplus.log.file}" substring="ORA-"/>
            <contains string="${sqlplus.log.file}" substring="SP2-"/>
        </or>
    </condition>

    <fail message="sql errors have been found during compilation" if="has.sql.errors"/>

</target>

Ainsi, la tâche échouera si en sortie du chargement des scripts on détecte la présence du motif ORA- ou SP2-. Il ne reste plus qu’à configurer votre projet Hudson pour qu’il appelle la tâche que vous venez d’écrire. De cette façon, si vos scripts comportent des erreurs ou si votre schéma de base de données ne peut plus les supporter, alors Hudson vous enverra une notification par mail (ou jabber, à vous de voir).

Cette solution de contournement peut être appliquée à d’autres langages à moins que ceux-ci ne soient déjà gérés par des plugins.

Voilà ! Ce sera tout pour aujourd’hui.

Bonne intégration continue à tout le monde et à la prochaine  ^_^°.

Share
  1. Pierre-Yves RICAU
    21/04/2010 à 07:03 | #1

    Notez qu’Hudson est au coeur de l’actualité ces derniers jours, puisque développeur principal, Kohsuke Kawaguchi, vient de quitter Sun/Oracle. Mais rien à craindre pour Hudson, puisqu’il compte justement s’y consacrer à plein temps et créer une startup autour d’Hudson.

    Sinon, mes collègues me soufflent qu’un plugin essentiel n’a pas été cité ici : le plugin ChuckNorris ;-)

  2. 21/04/2010 à 21:18 | #3

    Juste une petite rectification sur les Tasks: Eclipse permet de personnaliser totalement les tags reconnus, et de les trier par importance! TODO, FIXME, ou même toute autre tag…

    • Alexandre DERGHAM
      22/04/2010 à 11:00 | #4

      Au temps pour moi, je suis passé à coté de cette partie de la configuration.

  3. Matthieu Proucelle
    22/04/2010 à 12:39 | #5

    Merci Alex pour cet article ;)

    Hudson est un très bon serveur d’intégration, et la plupart des plugins que tu présente proposent des fonctions très intéressantes.

    Cependant je suis étonné de ne pas voir apparaitre le plugin Sonar, qui va permettre de rassembler d’une part les plugins checkstyle, warning, et cobertura que tu présente, mais aussi de produire des rapports très complets sur la qualité du projet (grâce entre autres à pmd, findbugs, et bien d’autres) et de nombreux metrics.

    Je citerais aussi la fonction Time Machine qui permet de voire la progression du projet dans le temps par rapport a de nombreux paramètres.

    Peut être découvrirons nous cela dans un prochain article ;)

    Pour finir le plugin email-ext permet une gestion avancé des alertes par mail (envoi de mail aux commiters et aux project owners lors du fail d’un build ou lors du retour a l’état normal etc…)

    Links :
    http://wiki.hudson-ci.org/display/HUDSON/Email-ext+plugin
    http://www.sonarsource.org/
    http://wiki.hudson-ci.org/display/HUDSON/Sonar+Plugin

  4. Maxime PICQUE
    23/04/2010 à 14:00 | #6

    Voila un bon article mais je tiens à préciser une chose :

    Hudson étant basé sur Maven, il peut souffrir d’une moins bonne intégration avec des projets Ant.

    Par exemple, le plugin Sonar, bien que permettant d’instrumenter les projets Ant (le plugin Sonar d’Hudson utilise sur le plugin Sonar de Maven), ne permet pas d’avoir un découpage des résultats “par module” (à la Maven).
    Ceci fait donc perdre un niveau de mesure intéressant dans Sonar.
    Les résultats de l’instrumentation restent cependant exploitable ;)

  1. 14/05/2010 à 15:43 | #1