Automatisation : Mercurial et Redmine

Portrait de ctxnop

Bonjour à tous.
Comme je le disais dans un précédent article, je vais, au fur et à mesure que j'en ai le temps, créer de l'automatisation sur mes sites et leurs contenus.
A l'occasion de la mise en place nouvelle fonctionnalité d'automatisation, je vais vous dévoiler un peu comment je m'y suis pris pour la génération automatique des documentations et en quoi consiste cette nouvelle fonctionnalité.

En premier lieu, étudions la problématique. Si un développeur archive du code dans le dépôt Mercurial, la documentation Doxygen qu'il a rédigé n'est pas mise à jour pour autant. Il est alors nécessaire de la générer puis la déployer sur Internet. Et donc pour ce faire il faut les droits d'administration sur mon serveur, sans compter le temps que ca prend. En plus, si je part en vacance, plus aucune documentation ne sera mise à jour, et je serais obligé de surveiller fréquemment si un projet à été mis à jour.

La solution est donc de poser un "hook" sur le dépôt Mercurial. Le principe d'un hook est simple, c'est un script qui sera exécuté lorsque que le dépôt émettra un évènement. Ainsi, on utilise généralement un évènement de "post-commit" qui a lieu après chaque mise à jour du dépôt.

Tout d'abord, on configure le fichier de configuration du dépôt pour ajouter les hook :

/etc/mercurial/hgweb.config

  1. [web]
  2. baseurl =
  3. push_ssl = false
  4. contact = ctxnop@gmail.com
  5.  
  6. [collections]
  7. /var/mercurial = /var/mercurial
  8.  
  9. [hooks]
  10. changegroup = /var/sys_scripts/mercurial/hook_script.sh changegroup
  11. commit = /var/sys_scripts/mercurial/hook_script.sh commit
  12. incoming = /var/sys_scripts/mercurial/hook_script.sh incoming
  13. outgoing = /var/sys_scripts/mercurial/hook_script.sh outgoing
  14. prechangegroup = /var/sys_scripts/mercurial/hook_script.sh prechangegroup
  15. precommit = /var/sys_scripts/mercurial/hook_script.sh precommit
  16. preoutgoing = /var/sys_scripts/mercurial/hook_script.sh preoutgoing
  17. pretag = /var/sys_scripts/mercurial/hook_script.sh pretag
  18. pretxnchangegroup = /var/sys_scripts/mercurial/hook_script.sh pretxnchangegro

On voit que j'ai tout simplement posé le même hook sur tous les évènements, en passant le nom de celui-ci en paramètre.

Voyons ensuite ce fichier de hook :

  1. #!/bin/sh
  2. TODO_PATH="/var/sys_scripts/mercurial/todo/"
  3. REPOS=$( basename $( pwd ) )
  4. CURPWD=$PWD
  5.  
  6. case $1 in
  7. "incoming")
  8.         touch $TODO_PATH/$REPOS
  9. ;;
  10. esac

Comme on le voit, le script est très simple. En réalité il ne fait que faire un "touch" sur un fichier du même nom que le dépôt. Si le fichier n'existe pas, il est créé.

C'est ensuite qu'intervient réellement la génération automatique de documentation.
Tout ce système ne sert qu'a une chose : ne générer les documentation qu'une fois par jour et uniquement pour les dépôts ayants été mis à jour. En effet, générer la documentation dans le script du hook signifie qu'au moindre petit commit, toute la documentation de tous mes dépôts est générée et déployée. Du coup, cette petite astuce permet de créer un fichier du nom du dépôt dans un répertoire dédié à ce mécanisme. Ensuite, viens une tâche cron qui va scanner ce répertoire et générer les documentations correspondantes.

Voici le script exécuté par cron toutes les nuits :

  1. #!/bin/bash
  2.  
  3. TODO_PATH="/var/sys_scripts/mercurial/todo/*"
  4.  
  5. #Pour chaque fichier présents dans le répertoire
  6. for repos in $TODO_PATH; do
  7.         #On extrait le nom du dépôt via le nom du fichier
  8.         REPOSITORY=$( basename $repos )
  9.  
  10.         # Si le répertoire était vide, on quitte
  11.         if [ "$REPOSITORY" = "*" ]; then
  12.                 exit
  13.         fi
  14.  
  15.         #On créer un répertoire remporaire au nom du dépôt dans lequel on va obtenir les sources de celui-ci
  16.         mkdir /var/tmp/$REPOSITORY
  17.         cd /var/tmp/$REPOSITORY
  18.         hg clone /var/mercurial/$REPOSITORY ./
  19.  
  20.         # S'il existe un fichier nomme Doxyfile a la racine du dépôt
  21.         if [ -f ./Doxyfile ]; then
  22.                 # Alors on génère la documentation et on la déploie dans le répertoire qui va bien, Apache n'a plus qu'a faire son boulot
  23.                 doxygen ./Doxyfile
  24.                 if [ $? -eq 0 ]; then
  25.                         rm -rf /var/www/documentations/$REPOSITORY
  26.                         cp -rf ./doc/htm /var/www/documentations/$REPOSITORY
  27.                 fi
  28.         fi
  29.         cd -
  30.         #On nettoie le travail intermédiaire.
  31.         rm -rf /var/tmp/$REPOSITORY
  32.         rm $repos
  33.  
  34. done

Et voilà.

Un autre de mes problème est Redmine et ses flux Atom. il ne les met à jour que lorsqu'un visiteur passe sur la page de dépôt d'un projet, mettant ainsi à jour le flux de ce projet.
En conséquence, j'ai modifié le script du hook précédent pour qu'en plus de créer un fichier via la commande touch, celui-ci invoque un script écrit pour Redmine, en passant en paramètre le nom du dépôt, et dont voici le code voici :

  1. #!/usr/bin/env /var/www/redmine/script/runner
  2. Project.find_by_identifier(File.basename(ARGV[0])).repository.fetch_changesets

Et voilà le travail.

Commentaires

Poster un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <br> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <h2> <h3> <img> <pre> <p>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <asm>, <bash>, <c>, <cil>, <cmake>, <cpp>, <cppqt>, <csharp>, <diff>, <drupal5>, <drupal6>, <ini>, <java>, <javascript>, <latex>, <lisp>, <lua>, <make>, <mysql>, <perl>, <php>, <plsql>, <powershell>, <prolog>, <python>, <reg>, <ruby>, <sql>, <tcl>, <tsql>, <vb>, <vbnet>, <xml>. The supported tag styles are: <foo>, [foo], [[foo]].

Plus d'informations sur les options de formatage

CAPTCHA
Cette question permet de bloquer les robots et l'envoie automatisé de spam.