5.4. Configurer la Gestion du Code Source

Dans son rôle le plus basique, un serveur d'Intégration Continue surveille votre système de gestion de version et vérifie les derniers changements au fur et à mesure. Le serveur compile et test alors la version la plus récente du code. Il peut alternativement récupérer et construire simplement la dernière version de votre code source de manière régulière. Dans tous les cas, une forte intégration avec votre système de gestion de version est essentielle.

De par leur rôle fondamental, les options de configuration du SCM sont identiques au travers de tous les types de tâches de build dans Jenkins. Jenkins supporte CVS et Subversion nativement, embarque un support pour Git et s'intègre avec un grand nombre d'autres systèmes de gestion de version via des plugins. A l'écriture de ce livre, le support par plugin inclus Accurev, Bazaar, BitKeeper, ClearCase, CMVC, Darcs, Dimensions, Git, CA Harvest, Mercurial, Perforce, PVCS, Rational Team Concert, StarTeam, Surround SCM, CM/Synergy, Microsoft Team Foundation Server et même Visual SourceSafe. Dans le reste de cette section, nous verrons comment configurer quelques uns des SCM les plus courants.

5.4.1. Travailler avec Subversion

Subversion est l'un des systèmes de gestion de version parmi les plus utilisés, et Jenkins embarque un support complet de Subversion (voir Figure 5.6, “Jenkins embarque par défaut le support pour Subversion”). Pour utiliser du code source provenant d'un dépôt Subversion, vous devez simplement fournir l'URL correspondante - cela fonctionnera parfaitement avec n'importe lequel des trois protocoles utilisés par Subversion (http, svn ou file). Jenkins vérifiera que l'URL est valide aussitôt que vous l'aurez remplie. Si le dépôt nécessite une authentification, Jenkins vous questionnera alors sur vos identifiants automatiquement et les enregistrera pour tout autre tâche de build qui aura besoin d'accéder à ce même dépôt.

Jenkins embarque par défaut le support pour Subversion

Figure 5.6. Jenkins embarque par défaut le support pour Subversion


Par défaut, Jenkins récupérera le contenu du dépôt dans un sous-répertoire de votre espace de travail, dont le nom sera celui du dernier élément de l'URL Subversion. Donc si votre URL Subversion est svn://localhost/gameoflife/trunk, Jenkins récupérera le contenu du dépôt dans une répertoire nommé trunk dans l'espace de travail de votre tâche de build. Si vous préférez nommer votre répertoire différemment, remplissez le nom que vous souhaitez dans le champ Local module directory. Mettez un point (“.”) dans le champ si vous souhaitez mettre le code source directement à la racine de l'espace de travail.

Occasionnellement, vous aurez besoin de récupérer du code source de plusieurs URLs Subversion. Dans ce cas, utilisez le bouton “Add more locations...” pour ajouter autant de dépôts sources que vous en avez besoin.

Une bonne procédure de build ne devrait pas modifier le code source ou laisser de fichiers supplémentaires qui pourrait porter à confusion votre système de gestion de version ou la procédure de build. Les artefacts générés et fichiers temporaires (comme les fichiers de journaux, rapports, données de test ou bases de données fichier) devraient être créés dans un répertoire séparé et créé spécifiquement pour ce besoin (tout comme le répertoire target dans les builds Apache Maven), et/ou être configurés pour être ignorés par le dépôt de votre système de gestion de version. Ces fichiers devrait également être supprimés par la procédure de build, une fois que le build n'en a plus besoin. Cela prend également une grande importance dans l'assurance de construire une procédure de build propre et reproductible—pour une version donnée de votre code source, le build devrait se comporter exactement de la même manière, peu importe où et quand il est exécuté. Les changements locaux, et la présence de fichiers temporaires, peuvent potentiellement compromettre cela.

Vous pouvez finement configurer la manière dont Jenkins récupère la dernière version de votre code source en sélectionnant la valeur attendue dans la liste déroulante Check-out Strategy. Si votre projet est correctement configuré, vous pouvez cependant accélérer grandement les choses en choisissant “Use ‘svn update’ as much as possible”. Il s'agit de l'option la plus rapide mais elle laisse les artefacts et fichiers des builds précédents dans votre espace de travail. Pour vous positionner du côté de la sécurité, vous pouvez choisir la seconde option (“Use ‘svn update’ as much as possible, with ‘svn revert’ before update”), qui exécutera systématiquement svn revert avant de lancer svn update. Cela vous assurera qu'aucun fichier n'aura été modifié localement. Cependant, cela ne supprimera pas les fichiers nouvellement créés pendant la procédure de build. Sinon, vous pouvez demander à Jenkins de supprimer tous les fichiers à ignorer ou non versionnés avant de faire un svn update ou encore jouer la carte de la sécurité et récupérer une copie propre et complète à chaque build.

Une autre fonctionnalité de Jenkins particulièrement utile est sont intégration avec les navigateurs de code source. Un bon navigateur de code source est un élément important de votre configuration d'Intégration Continue. Cela vous permet de voir d'un coup d'œil les changements qui sont à l'origine du lancement de votre build, ce qui est très utile quand vous avez besoin de localiser un problème lors d'un build échoué (voir Figure 5.7, “Navigateur de code source montrant les changements dans le code qui ont causé le build.”). Jenkins intègre la plupart des principaux navigateurs de source code, y compris des outils open source comme WebSVN ou Sventon, ainsi que ceux commerciaux tels qu'Atlassian FishEye.

Navigateur de code source montrant les changements dans le code qui ont causé le build.

Figure 5.7. Navigateur de code source montrant les changements dans le code qui ont causé le build.


Jenkins vous permet également d'affiner la sélection des changements qui déclencheront un build. Dans la section avancée, vous pouvez utiliser le champ Régions exclues pour dire à Jenkins de ne pas déclencher de build si certains fichiers sont modifiés. Ce champ prend en compte une liste d'expressions régulières qui identifient les fichiers qui ne doivent pas déclencher de build. Par exemple, supposez que vous ne voulez pas que Jenkins démarre un build si seulement des images ont été modifiées. Pour ce faire, vous pouvez utiliser un groupe d'expressions régulières comme celles qui suivent :

/trunk/gameoflife/gameoflife-web/src/main/webapp/.*\.jpg
/trunk/gameoflife/gameoflife-web/src/main/webapp/.*\.gif
/trunk/gameoflife/gameoflife-web/src/main/webapp/.*\.png

De manière alternative, vous pouvez spécifier uniquement les Régions Incluses, si vous n'êtes intéressé que par les changements d'une partie de votre arbre de code source. Vous pouvez même combiner les champs Régions exclues et Régions Incluses — dans ce cas, un fichier modifié ne déclenchera un build que s'il est inclus dans les Régions Incluses mais pas dans les Régions Exclues.

Vous pouvez également ignorer les changements provenant de certains utilisateurs (Utilisateurs Exclus), ou pour certains messages de commit en particulier (Excluded Commit Messages). Par exemple, si votre projet utilise Maven, vous pourrez être amené à utiliser le plugin Maven Release Plugin pour promouvoir votre application d'une version snapshot vers une version release officielle. Ce plugin poussera automatiquement le numéro de version de votre application depuis sa version snapshot utilisée pendant le développement (comme par exemple 1.0.1-SNAPSHOT) vers une version release (1.0.1), empaquettera, déploiera votre application avec ce numéro de version et le mettra à jour avec le prochain numéro de version snapshot (par exemple 1.0.2-SNAPSHOT) pour les développements futurs. Pendant cette procédure, Apache Maven s'occupe de multiples étapes comptables comme d'effectuer le commit du nouveau numéro de version, de créer la nouvelle étiquette pour la livraison de votre application et enfin faire l'opération de commit pour le nouveau numéro de version snapshot.

Supposez maintenant que vous avez une tâche de build spécifique pour effectuer une nouvelle livraison utilisant cette procédure. Les différentes opérations de commits générées par le plugin Maven Release Plugin devraient normalement déclencher des tâches de build dans Jenkins. Cependant, comme votre tache de build de livraison est déjà en train de compiler et tester cette version de votre application, vous n'avez pas besoin que Jenkins le fasse à nouveau dans une autre tâche de build. Pour s'assurer que Jenkins ne déclenche pas un autre build dans ce cas, vous pouvez utiliser le champ Excluded Commit Messages avec la valeur suivante :

[maven-release-plugin] prepare release.*

Cela vous assurera que Jenkins sautera les changements correspondant à des nouvelles versions de release mais pas ceux correspondant à la prochaine version snapshot.

5.4.2. Travailler avec Git

Contribué par Matthew McCullough

Git est un système de gestion de version distribué qui est le successeur logique de Subversion et un concurrent à Mercurial partageant le même esprit. Le support de Git dans Jenkins est mature et complet. Il y a également plusieurs plugins qui peuvent contribuer au workflow général de Git dans Jenkins. Nous commencerons par nous intéresser au plugin Git qui apporte le support des fonctions principales de Git. Nous aborderons le sujet des plugins supplémentaires brièvement.

5.4.2.1. Installation du plugin

Le plugin Git est disponible dans le Gestionnaire de Plugins Jenkins et est documenté sur sa propre page de wiki. Le plugin suppose que Git (version 1.3.3 ou ultérieure) a été installé sur le serveur de build. Vous devrez donc vous en assurer préalablement. Vous pouvez vous en assurer en exécutant la commande suivante sur votre serveur de build :

$ git --version
git version 1.7.1

Revenez ensuite à Jenkins et cochez la case correspondante dans le gestionnaire de plugins Jenkins et cliquez sur le bouton d'installation.

5.4.2.1.1. Configuration système du plugin

Après l'installation du plugin Git, une nouvelle section de configuration est disponible dans la page Administrer JenkinsConfigurer le système (voir Figure 5.8, “Configuration système du plugin Git”). Vous devez en particulier fournir le chemin vers l'exécutable de Git. Si Git est déjà installé sur votre système, entrez simplement “git” dans le champ.

Configuration système du plugin Git

Figure 5.8. Configuration système du plugin Git


5.4.2.1.2. Configuration de la clé SSH

Si le dépôt Git auquel vous accédez utilise SSH sans mot de passe comme moyen d'authentification—par exemple si l'adresse d'accès ressemble à git@github.com:matthewmccullough/some-repo.git—vous devrez fournir la partie privée de la clé sous forme de fichier ~/.ssh/id_rsa~ est le répertoire racine du compte utilisateur exécutant Jenkins.

L'empreinte du serveur distant devra additionnellement être ajoutée dans ~/.ssh/known_hosts pour éviter que Jenkins ne vous invite à accepter l'autorisation vers le serveur Git lors du premier accès alors que la console sera non interactive.

Alternativement, si vous avez la possibilité de vous connecter avec l'utilisateur jenkins, accédez par SSH à la machine Jenkins en tant que jenkins et faites une tentative manuelle de cloner un dépôt Git distant. Cela testera la configuration de votre clé privée et remplira le fichier known_hosts dans le répertoire ~/.ssh. C'est probablement la solution la plus simple de vous familiariser avec les subtilités de la configuration SSH.

5.4.2.2. Utilisation du plugin

Que cela soit dans un nouveau projet Jenkins ou dans un projet existant, une nouvelle option de Gestion du Code Source pour Git sera affichée. Dès lors, vous pouvez configurer une ou plusieurs adresses de dépôts (voir Figure 5.9, “Remplir une URL de dépôt Git”). Un seul dépôt est utilisé dans la majorité des projets. Ajouter un second dépôt peut être utile dans des cas plus compliqués et vous permet de spécifier des cibles distinctes pour les opérations de pull et de push.

5.4.2.2.1. Configuration avancée par projet de la gestion du code source

Dans la plupart des cas, l'URL du dépôt Git que vous utilisez devrait être suffisante. Cependant, si vous avez besoin de plus d'options, cliquez sur le bouton Avancé (voir Figure 5.10, “Configuration avancée d'une URL de dépôt Git”). Cela apporte un contrôle plus précis sur le comportement du pull.

Le Nom du dépôt est un titre raccourci (ou remote en langage Git) pour un dépôt donné auquel vous pouvez vous reporter plus tard dans la configuration de l'action de merge.

La Refspec est un terme spécifique du langage Git pour contrôler précisément ce qui est récupéré depuis les serveurs distants et sous quel espace de nom c'est stocké localement.

5.4.2.2.2. Branches à construire

Le champ Branch Specifier (Figure 5.11, “Configuration avancée des branches Git à construire”) peut être utilisé à l'aide d'un caractère générique ou en spécifiant le nom d'une branche à construire par Jenkins. Si le champ est laissé vide, toutes les branches seront construites. Pour le moment, lorsque vous sauvegardez votre tâche pour la première fois et qu'elle est configurée avec ce champ vide, il est alors rempli avec **, ce qui signifie "construire toutes les branches".

Remplir une URL de dépôt Git

Figure 5.9. Remplir une URL de dépôt Git


Configuration avancée d'une URL de dépôt Git

Figure 5.10. Configuration avancée d'une URL de dépôt Git


Configuration avancée des branches Git à construire

Figure 5.11. Configuration avancée des branches Git à construire


5.4.2.2.3. Régions exclues

Les régions (vues dans Figure 5.12, “Branches et régions”) sont des chemins nommés spécifiquement ou génériques de votre code source qui, même une fois modifiés, ne doivent pas déclencher de build. Il s'agit généralement de fichiers non compilés tels que les archives de locales ou d'images qui n'ont à priori pas d'effet sur les tests unitaires ou d'intégration.

Branches et régions

Figure 5.12. Branches et régions


5.4.2.2.4. Utilisateurs Exclus

Le plugin Git vous permet également d'ignorer certains utilisateurs même s'ils effectuent des changements du code source qui auraient dû normalement déclencher un build.

Cette action n'est pas aussi méchante qu'elle peut paraitre : les utilisateurs exclus sont généralement des utilisateurs automatisés ou des développeurs non humains, qui ont des comptes distincts avec des droits de commit sur le gestionnaire de code source. Ces utilisateurs automatisés font généralement de petites opérations comme incrémenter la version d'un fichier pom.xml plutôt que de véritables changements dans la logique de votre application. Si vous souhaitez exclure plusieurs utilisateurs, ajoutez les simplement sur des lignes séparées.

5.4.2.2.5. Récupérer/fusionner sur une branche locale

Parfois vous aurez le besoin de récupérer directement le HEAD de manière séparée dans une branche au travers du hash d'un commit. Dans ce cas, spécifiez votre branche locale dans le champ “Checkout/merge to a local branch”.

Il est plus simple de l'illustrer par un exemple. Sans spécifier de branche locale, le plugin ferait quelque chose comme cela :

git checkout 73434e4a0af0f51c242f5ae8efc51a88383afc8a

Autrement, si vous utilisiez une branche nommée maBranche, Jenkins ferait la chose suivante :

git branch -D maBranche
git checkout -b maBranche 73434e4a0af0f51c242f5ae8efc51a88383afc8a
5.4.2.2.6. Dépôt dans un sous-répertoire local

Par défaut, Jenkins clonera le dépôt Git directement dans l'espace de travail de votre tâche de build. Si vous préférez utiliser un répertoire différent, vous pouvez le spécifier ici. Notez que ce répertoire est relatif à l'espace de travail de votre tâche de build.

5.4.2.2.7. Fusionner avant le build

Le cas typique d'utilisation de cette option est le remplissage d'une branche d'intégration proche de la branche master. N'oubliez pas que seulement les fusions ne présentant pas de conflit seront effectuées automatiquement. Les fusions plus complexes qui requièrent une intervention manuelle feront échouer le build.

La branche fusionnée qui en résulte ne sera pas poussée automatiquement à moins que l'action de push ne soit activée dans les actions post-build.

5.4.2.2.8. Tailler les branches distantes avant le build

Le taillage supprime les copies locales de branches distantes qui proviennent d'un clone précédent mais qui ne sont plus présentent sur le dépôt distant. En résumé, il s'agit du nettoyage du clone local pour qu'il soit parfaitement synchronisé avec son jumeau distant.

5.4.2.2.9. Nettoyer après récupération

Active la purge de tout fichier ou répertoire non versionné, ramenant le votre copie de travail à son étât vierge.

5.4.2.2.10. Mise à jour récursive des sous-modules

Si vous utilisez les fonctionnalités de sous-modules de Git dans votre projet, cette option vous assure que chaque sous-module est à jour grâce à un appel explicite à la commande update, même si les sous-modules sont imbriqués dans d'autres sous-modules.

5.4.2.2.11. Utiliser l'auteur du commit dans changelog

Jenkins note et affiche l'auteur du changement de code dans une vue synthétique. Git note l'auteur et le commiter du code distinctement, et cette option vous permet de choisir lequel apparaîtra dans le changelog.

5.4.2.2.12. Effacer l'espace de travail

Typiquement Jenkins réutilisera l'espace de travail, le rafraîchissant simplement si nécessaire et si vous avez activé l'option “Clean after checkout”, nettoiera les fichiers non versionnés. Cependant, si vous préférez avoir un espace de travail complétement propre, vous pouvez utiliser l'option “Wipe out workspace” pour supprimer et reconstruire l'espace de travail de zéro. Gardez à l'esprit que cela allongera significativement le temps d'initialisation et de construction du projet.

5.4.2.2.13. Choix de la stratégie

Jenkins decide quelle branches il doit construire en se basant sur une certaine stratégie (voir Figure 5.13, “Choix de la stratégie”). Les utilisateurs peuvent influencer cette procédure de recherche de branche. Le choix par défaut est de rechercher tous les HEADs de branche. Si le plugin Gerrit est installé, d'autres options pour construire tous les commits notifiés par Gerrit seront affichées.

Choix de la stratégie

Figure 5.13. Choix de la stratégie


5.4.2.2.14. Exécutable Git

Dans les options globales de Jenkins (voir Figure 5.14, “Configuration globale de l'exécutable de Git”), plusieurs exécutables Git peuvent être configurés et utilisés build par build. Cela est rarement utilisé et l'est seulement lorsqu'un clone ou d'autres opérations Git sont sensibles à une version particulière de Git. Git tend à être très flexible quant à ses numéro de version ; les dépôts légèrement anciens peuvent être clonés très facilement avec une nouvelle version de Git et inversement.

Configuration globale de l'exécutable de Git

Figure 5.14. Configuration globale de l'exécutable de Git


5.4.2.2.15. Navigateur de dépôt

Tout comme Subversion, Git a plusieurs navigateurs de source qu'il peut utiliser. Les plus couramment utilisés sont Gitorious, Git Web, ou GitHub. Si vous fournissez l'URL correspondante à votre navigateur de dépôt, Jenkins pourra alors afficher un lien direct vers les changements de votre code source qui ont déclenché le build (voir Figure 5.15, “Navigateur de dépôt”).

Navigateur de dépôt

Figure 5.15. Navigateur de dépôt


5.4.2.3. Déclencheurs de build

Le plugin Git de base offre la possibilité de scruter l'outil de gestion de version régulièrement et de vérifier si de nouveau changements ont eu lieu depuis la dernière requête. Si des changements sont présents, un build est alors lancé. Le journal de scrutation (montré dans Figure 5.16, “Journal de scrutation”) est accessible par un lien dans la partie gauche de la page dans la barre de navigation lorsque vous visitez une tâche spécifique. Vous y trouverez les informations sur la dernière fois que le dépôt a été scruté et s'il a renvoyé une liste de changements (voir Figure 5.17, “Résultats de la scrutation de Git”).

Journal de scrutation

Figure 5.16. Journal de scrutation


La scrutation de Git est disponible dans un format plus orienté développeur qui montre les commentaires de commit ainsi que des hyperliens pointant vers une vue plus détaillée des utilisateurs et des fichiers modifiés.

Résultats de la scrutation de Git

Figure 5.17. Résultats de la scrutation de Git


Installer le Gerrit Build Trigger ajoute une option Gerrit event qui peut être plus efficace et précise que de simplement scruter le dépôt.

5.4.2.3.1. Déclenchement par Gerrit

Gerrit est une application web open source qui facilite les revues de code pour les projets dont les sources sont gérées par Git. Il lit le dépôt Git traditionnel et apporte une comparaison côte-à-côte des changements. Lorsque le code est revu, Gerrit apporte alors un lieu pour commenter et déplacer le patch dans un état ouvert, fusionné ou abandonné.

Le Gerrit Trigger est un plugin Jenkins qui peut déclencher un build Jenkins sur du code quand n'importe quelle activité liée à un utilisateur spécifique survient dans le projet d'un utilisateur défini du dépôt Git (voir Figure 5.18, “Déclenchement par Gerrit”). Il s'agit d'une alternative aux options plus régulièrement utilisées comme la construction périodique ou la scrutation de l'outil de gestion de version.

Déclenchement par Gerrit

Figure 5.18. Déclenchement par Gerrit


La configuration de ce plugin est minimale et focalisée sur le Type du Projet et son Pattern ainsi que le Type de Branches et leur Pattern. Dans chaque paire, le type peut être Plain, Path ou bien RegExpdescriptif de ce qu'il faut observer — et la valeur (pattern) à évaluer en utilisant le type type comme guide.

5.4.2.4. Actions post-build

Le plugin Git pour Jenkins ajoute des capacités spécifiques à Git au post-traitement des artefacts du build. Plus spécifiquement, le Git Publisher (montré dans Figure 5.19, “Git Publisher”) permet les actions de merge et de push. Cochez la case du Git Publisher pour afficher ses quatres options.

Git Publisher

Figure 5.19. Git Publisher


5.4.2.4.1. Pousser seulement si le build est réussi

Si une fusion ou tout autre action entraînant la création d'un commit a été faite pendant le build Jenkins, cette option peut alors être activée pour pousser les changements dans le dépôt distant.

5.4.2.4.2. Fusionner les résultats

Si une fusion au début du build a été configurée, la branche résultante est alors poussée vers son origine (voir Figure 5.20, “Fusionner les résultats”).

Fusionner les résultats

Figure 5.20. Fusionner les résultats


5.4.2.4.3. Étiquettes

Lorsque vous poussez des étiquettes, chacune d'elle peut être nommée et choisie d'être créée si elle n'existe pas (ce qui échoue si elle existe déjà). Les variables d'environnement peuvent être utilisées dans le nom des étiquettes. Par exemple vous pouvez utiliser l'ID du process avec HUDSON_BUILD_$PPID ou même le numéro de build s'il est fourni par un plugin Jenkins avec $HUDSON_AUTOTAG_$BUILDNUM. Les étiquettes peuvent être ciblées sur un dépôt distant spécifique comme origin ou integrationrepo.

5.4.2.4.4. Branches

Le HEAD courant utilisé dans le build Jenkins d'une application peut être poussé dans d'autres dépôts distants lors d'une étape suivant le build. Vous n'avez à spécifier que la branche de destination et le nom du dépôt distant.

Les noms des dépôts distants sont validés en comparaison à la configuration précédemment faite du plugin. Si le dépôt n'existe pas, un avertissement est affiché.

5.4.2.5. Plugin GitHub

Le plugin GitHub offre deux points d'intégration. Premièrement, il apporte un lien optionnel vers la page de démarrage du projet sur GitHub. Entrez simplement l'URL du projet (sans la partie tree/master ou tree/branch). Par exemple, http://github.com/matthewmccullough/git-workshop.

Ensuite, le plugin GitHub plugin permet d'obtenir un lien par fichier modifié qui sera relié directement au navigateur de dépôt via la section de gestion du code source (voir Figure 5.21, “Navigateur de dépôt GitHub”).

Navigateur de dépôt GitHub

Figure 5.21. Navigateur de dépôt GitHub


Avec le choix de githubweb comme navigateur de dépôt, tout fichier sur lequel des changements auront été détectés sera lié à la page web de visualisation du source appropriée sur GitHub (Figure 5.22, “Navigateur de dépôt GitHub”).

Navigateur de dépôt GitHub

Figure 5.22. Navigateur de dépôt GitHub