Rédigé par Evgeny Goldin
Comme mentionné dans la section précédente, le nombre de tâches de build que votre serveur Jenkins héberge peut varier. Lorsque ce nombre grossira, il deviendra plus difficile non seulement de les voir dans le tableau de bord Jenkins, mais aussi de les configurer. Imaginez ce que nécessiterait la configuration de 20 à 50 tâches une par une ! De plus, plusieurs de ces tâches pourraient avoir en commun des éléments de configuration, comme des goals Maven ou des paramètres de configuration mémoire, ce qui résulte en une configuration dupliquée et un surplus de maintenance.
Par exemple, si vous décidez d'exécuter mvn
clean install
au lieu de mvn clean
deploy
pour vos tâches de release et de passer à des méthodes de
déploiement alternatives, comme celles fournies par le pluginArtifactory
, vous n'aurez plus d'autre choix que d'ouvrir toutes les
tâches concernées et de les mettre à jour manuellement.
Sinon, vous pourriez tirer parti du fait que Jenkins est un outil
simple et direct qui garde trace de toutes ses définitions sur le disque
dans des fichiers bruts. En effet, vous pouvez mettre à jour les
fichiers config.xml
de vos tâches
directement dans le répertoire .jenkins/jobs
où ils sont conservés. Bien que
cette approche fonctionnerait, elle est loin d'être idéale parce qu'elle
implique un nombre assez important de sélections manuelles et de
remplacements délicats dans des fichiers XML Jenkins.
Il y a une troisième façon d'atteindre le nirvana des mises à jour
massives de tâches : générer vos fichiers de configuration automatiquement
en utilisant une sorte de fichier de définition. Le Maven Jenkins
Plugin fait exactement cela : générer les fichiers config.xml
pour toutes les tâches en utilisant
des définitions standards conservées dans un unique fichier pom.xml
.
Quand vous configurez une tâche avec le Maven Jenkins Plugin, vous pouvez définir tous les éléments habituels de configuration, comme les goals Maven, l'emplacement du POM, les URL de dépôts, les adresses e-mail, le nombre de jours pendant lesquels conserver les logs, et ainsi de suite. Le plugin essaie de vous rapprocher au plus près de la configuration classique d'une tâche dans Jenkins.
Jetons un oeil à la tâche de build de Google Guice :
<job> <id>google-guice-trunk</id> <description>Building Google Guice trunk.</description> <descriptionTable> <row> <key>Project Page</key> <value> <a href="http://code.google.com/p/google-guice/"> <b><code>code.google.com/p/google-guice</code></b> </a> </value> <escapeHTML>false</escapeHTML> <bottom>false</bottom> </row> </descriptionTable> <jdkName>jdk1.6.0</jdkName> <mavenName>apache-maven-3</mavenName> <mavenOpts>-Xmx256m -XX:MaxPermSize=128m</mavenOpts> <daysToKeep>5</daysToKeep> <useUpdate>false</useUpdate> <mavenGoals>-e clean install</mavenGoals> <trigger> <type>timer</type> <expression>0 0 * * *</expression> </trigger> <repository> <remote>http://google-guice.googlecode.com/svn/trunk/</remote> </repository> <mail> <recipients>jenkins@evgeny-goldin.org</recipients> </mail> </job>
Cette tâche utilise un certain nombre de configurations standards
comme <jdkName>
, <mavenName>
et <mavenOpts>
. Le code est récupéré à
partir d'un dépôt Subversion (défini dans l'élément <repository>
), et un <trigger>
cron qui exécute la tâche
pendant la nuit à 00:00. Les notifications Email sont envoyées aux
personnes spécifiées avec l'élément <mail>
. Cette configuration ajoute aussi
un lien vers la page du projet dans le tableau de description généré
automatiquement pour chaque tâche.
Cette tâche générée est affichée dans votre serveur Jenkins comme illustré dans Figure 10.27, “Une tâche générée avec le Maven Jenkins plugin”.
Voici une autre tâche réalisant la build de la branche master du projet Jenkins hébergé chez GitHub :
<job> <id>jenkins-master</id> <jdkName>jdk1.6.0</jdkName> <numToKeep>5</numToKeep> <mavenName>apache-maven-3</mavenName> <trigger> <type>timer</type> <expression>0 1 * * *</expression> </trigger> <scmType>git</scmType> <repository> <remote>git://github.com/jenkinsci/jenkins.git</remote> </repository> <mail> <recipients>jenkins@evgeny-goldin.org</recipients> <sendForUnstable>false</sendForUnstable> </mail> </job>
Elle génère la tâche montrée dans Figure 10.28, “Tâche générée jenkins-master”.
La documentation du plugin fournit une référence détaille de tous les paramètres qui peuvent être configurés.
Être capable de générer des tâches Jenkins jobs en utilisant une configuration centralisée, comme un POM Maven, résout le problème de la création et de la mise à jour de plusieurs tâches à la fois. Tout ce que vous avez à faire est de modifier les définitions de job, relancer le plugin et charger les définitions mises à jour avec Administrer Jenkins→“Recharger la configuration à partir du disque”. Cette approche a aussi l'avantage de rendre facile le stockage de vos configurations de tâche dans un système de gestion de versions, ce qui rend par la même plus facile le suivi des changements faits aux configurations de build.
Cela ne résout toutefois pas le problème consistant à maintenir des tâches qui partagent un certain nombre de propriétés identiques, comme les goals Maven, les destinataires email ou l'URL du dépôt de code. Pour cela, le Maven Jenkins Plugin fournit de l'héritage de tâches, démontré dans l'exemple suivant:
<jobs> <job> <id>google-guice-inheritance-base</id> <abstract>true</abstract> <jdkName>jdk1.6.0</jdkName> <mavenName>apache-maven-3</mavenName> <daysToKeep>5</daysToKeep> <useUpdate>true</useUpdate> <mavenGoals>-B -e -U clean install</mavenGoals> <mail><recipients>jenkins@evgeny-goldin.org</recipients></mail> </job> <job> <id>google-guice-inheritance-trunk</id> <parent>google-guice-inheritance-base</parent> <repository> <remote>http://google-guice.googlecode.com/svn/trunk/</remote> </repository> </job> <job> <id>google-guice-inheritance-3.0-rc3</id> <parent>google-guice-inheritance-base</parent> <repository> <remote>http://google-guice.googlecode.com/svn/tags/3.0-rc3/</remote> </repository> </job> <job> <id>google-guice-inheritance-2.0-maven</id> <parent>google-guice-inheritance-base</parent> <mavenName>apache-maven-2</mavenName> <repository> <remote>http://google-guice.googlecode.com/svn/branches/2.0-maven/ </remote> </repository> </job> </jobs>
Dans cette configuration,
google-guice-inheritance-base est une tâche parent
abstraite contenant toutes les propriétés communes : le nom du JDK, le
nom de Maven, le nombre de jours de conservation des logs, la politique
de mise à jour SVN, les goals Maven et les destinataires email. Les
trois tâches suivantes sont très courtes, spécifiant simplement qu'elles
étendent une tâche <parent>
et
ajoutent les configurations manquantes (URLs de dépôt dans ce
cas). Une fois générées, elles héritent de
toutes les propriétés de la tâche parente
automatiquement.
Toute propriété héritée peut être rédéfinie, comme démontré dans la tâche google-guice-inheritance-2.0-maven où Maven 2 est utilisé à la place de Maven 3. Si vous voulez "annuler" une propriété hériétée, vous devrez la redéfinir avec une valeur vide.
L'héritage de tâches est un concept très puissant qui permet aux tâches de former des groupes hiérarchiques de n'importe quel type et dans n'importe quel but. Vous pouvez grouper vos tâches d'IC, noctures ou de release de cette façon, en centralisant les déclencheurs d'exécution partagés, les goals Maven ou les destinataires email dans des tâches parentes. Cette approche emprunté au monde orienté object permet de résoudre le problème de maintenance de tâches partageant un certain nombre de propriétés identiques.
En plus de configurer une tâche et de réutiliser ses définitions, vous pouvez bénéficier d'un support spécial pour un certain nombre de plugins Jenkins. À l'heure actuelle, une utilisation simplifiée des plugins Parameterized Trigger et Artifactory est fournie, un support pour d'autres plugins populaires est prévu dans de futures versions.
Ci-dessous se trouve un exemple d'invocation de tâches avec le plugin Parameterized Trigger. Utiliser cette option suppose que vous avez déjà ce plugin installé :
<job> <id>google-guice-inheritance-trunk</id> ... <invoke> <jobs> google-guice-inheritance-3.0-rc3, google-guice-inheritance-2.0-maven </jobs> </invoke> </job> <job> <id>google-guice-inheritance-3.0-rc3</id> ... </job> <job> <id>google-guice-inheritance-2.0-maven</id> ... </job>
L'élément <invoke>
vous
permet d'invoquer d'autres tâches chaque fois que la tâche courante se
termine correctement. Vous pouvez créer un pipeline de tâches de cette
façon, vous assurant que chaque tâche du pipeline invoque la suivante.
Notez que s'il y a plus d'un exécuteur Jenkins disponible au moment de
l'invocation, les tâches spécifiées démarreront en parallèle. Pour une
exécution en série, vous devrez connecter chaque tâche amont à une tâche
aval avec <invoke>
.
Par défaut, l'invocation ne se fait que quand la tâche courante est stable. Ceci peut être modifié, comme montré dans les exemples suivants :
<invoke> <jobs>jobA, jobB, jobC</jobs> <always>true</always> </invoke> <invoke> <jobs>jobA, jobB, jobC</jobs> <unstable>true</unstable> </invoke> <invoke> <jobs>jobA, jobB, jobC</jobs> <stable>false</stable> <unstable>false</unstable> <failed>true</failed> </invoke>
La première invocation dans l'exemple ci-dessus invoque toujours les tâches avals. Ceci peut être utilisé pour un pipeline de tâches qui devraient toujours être exécutées même si certaines, ou leurs tests, échouent.
La seconde invocation dans l'exemple ci-dessus invoque les tâches avals même si une tâche amont est instable : l'invocation prend place quels que soient les résultats des tests. Cela peut être utilisé pour un pipeline de tâches moins sensibles aux tests et à leurs échecs.
La troisième invocation ci-dessus invoque les tâches avals seulement quand une tâche amont échoue mais pas lorsqu'elle est stable ou instable. Cette configuration peut vous être utile si une tâche en échec doit effectuer des actions additionnelles autres que les notifications email tradtionnelles.
Artifactory est un dépôt de binaires à usage général qui peut être utilisé comme gestionnaire de dépôt Maven. Le plugin Jenkins Artifactory, montré dans Figure 10.29, “Configuration du plugin Jenkins pour Artifactory”, fournit un certain nombre d'avantages pour les tâches de build Jenkins. Nous avons déjà passé en revue quelques-unes d'entre elles dans Section 5.9.4, “Déployer vers un gestionnaire de dépôt d’entreprise”, notamment la capacité à déployer des artefacts à l'achèvement de la tâche ou d'envoyer avec des informations de l'environnement de build avec les artefacts pour une meilleure traçabilité.
Vous pouvez aussi utiliser le plugin Jenkins Artifactory conjointement au Maven Jenkins Plugin pour déployer dans Artifactory, comme montré dans l'exemple suivant :
<job> ... <artifactory> <name>http://artifactory-server/</name> <deployArtifacts>true</deployArtifacts> <includeEnvVars>true</includeEnvVars> <evenIfUnstable>true</evenIfUnstable> </artifactory> </job>
Les informations d'identité pour le déploiement sont spécifiées
dans la configuration de Jenkins dans l'écran Administrer Jenkins→Configurer le système. Elles peuvent aussi être
spécifiées pour chaque tâche Jenkins. Les dépôts Maven par défaut sont
libs-releases-local
et libs-snapshots-local
. Vous trouverez plus de
détails dans la documentation du plugin à l'adresse http://wiki.jenkins-ci.org/display/JENKINS/Artifactory+Plugin.
En supplément des tâches Maven, le Maven Jenkins Plugin vous permet de configurer des tâches freestyle Jenkins. Un exemple est montré ici :
<job> <id>free-style</id> <jobType>free</jobType> <scmType>git</scmType> <repository> <remote>git://github.com/evgeny-goldin/maven-plugins-test.git</remote> </repository> <tasks> <maven> <mavenName>apache-maven-3</mavenName> <jvmOptions>-Xmx128m -XX:MaxPermSize=128m -ea</jvmOptions> <properties>plugins-version = 0.2.2</properties> </maven> <shell><command>pwd; ls -al; du -hs .</command></shell> </tasks> </job>
Les tâches Freestyle vous permettent d'exécuter un shell ou une commande batch, exécuter Maven ou Ant, et invoquer d'autres tâches. Elles fournissent un environnement d'exécution bien pratique pour les scripts systèmes ou tout autre type d'activité qui n'est pas directement implémentée dans Jenkins ou l'un des ses plugins. En utilisant cette approche, vous pouvez générer des fichiers de configuration de tâche de build Freestyle de façon similaire à l'approche que nous avons vue pour les tâches de build Maven, ce qui peut aider à rendre votre environnement de construction plus cohérent et maintenable.