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.
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.
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.
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.
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.
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.
Après l'installation du plugin Git, une nouvelle section de configuration est disponible dans la page Administrer Jenkins→Configurer 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.
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
où ~
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.
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
.
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.
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".
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.
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.
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
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.
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.
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.
Active la purge de tout fichier ou répertoire non versionné, ramenant le votre copie de travail à son étât vierge.
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.
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.
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.
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.
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.
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”).
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”).
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.
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.
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.
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 RegExp — descriptif de ce qu'il faut observer — et la valeur (pattern) à évaluer en utilisant le type type comme guide.
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.
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.
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”).
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
.
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é.
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”).
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”).