Maintenant, Jenkins sait où et à quelle fréquence obtenir le code source du projet. La prochaine chose que vous devez expliquer à Jenkins est qu’est ce qu’il doit faire avec le code source. Dans un build Freestyle, vous pouvez faire ceci en définissant des étapes de build. Les étapes de build sont des blocs basiques de construction pour le processus de build Freestyle de Jenkins. C’est ce qui permet de dire à Jenkins exactement comment vous voulez que votre projet soit construit.
Une tâche de build peut avoir une étape, ou plusieurs. Il peut éventuellement n’en avoir aucune. Dans un build Freestyle, vous pouvez ajouter autant d’étapes de build que vous le souhaitez dans la section Build de la configuration de votre projet (voir la figure Figure 5.26, “Ajouter une étape de build à une tâche de build Freestyle”). Dans une installation Jenkins basique, vous serez capable d’ajouter des étapes pour invoquer Maven et Ant, aussi bien que lancer des commandes shell spécifique à l’OS ou des batchs Windows. Et en installant des plugins additionnels, vous pouvez aussi intégrer d’autres outils, comme Groovy, Gradle, Grailes, Jython, MSBuild, Phing, Python, Rake, et Ruby, juste pour nommer certains des outils les plus connus.
Dans le reste de cette section, nous allons plonger dans quelques-uns des types d’étapes de build les plus communs.
Jenkins a un excellent support de Maven, et les étapes de build Maven sont faciles à configurer et très flexibles. Il suffit de choisir « Invoquer les cibles Maven de haut niveau » depuis la liste des étapes de build, choisir une version de Maven à lancer (si vous avez plusieurs versions installées), et entrer les goals Maven que vous souhaitez lancer. Les tâches de build Freestyle de Jenkins fonctionnent biens avec Maven 2 et Maven 3.
Tout comme en ligne de commande, vous pouvez spécifier autant de goals individuels que vous le souhaitez. Vous pouvez aussi fournir des options en ligne de commande. Quelques options utiles de Maven dans un contexte IC sont :
-B
, --batch-mode
Cette option indique à Maven de ne pas demander d’entrée à l’utilisateur, en utilisant les valeurs par défaut si nécessaire. Si Maven demande n’importe quelle entrée durant un build Jenkins, le build sera bloqué indéfiniment.
-U
,
--update-snapshots
Force Maven à vérifier les mises à jour des dépendances de type release ou snapshot sur le dépôt distant. Cela vous permet d’être sûr que vous êtes en train de construire avec les dernières et les plus grandes dépendances snapshot, et pas uniquement les vieilles copies locales qui ne sont pas forcément synchronisées avec le code source.
-Dsurefire.useFile=false
Cette option force Maven à écrire la sortie JUnit dans la console, au lieu de le faire dans des fichiers textes dans le répertoire target comme c’est fait d’habitude. Avec ceci, n’importe quels détails de test en échec seront visibles directement dans la sortie console de la tâche de build. Les fichiers XML dont Jenkins a besoin pour ses rapports de test seront toujours générés.
Les options avancées sont également utiles (cliquez sur le bouton Avancé).
Le champ optionnel POM permet de surcharger l’emplacement par défaut du fichier pom.xml
. C’est l’équivalent de lancer Maven en ligne de commande avec l’option -f
ou --file
.
C’est utile pour certains projets multi modules où le fichier agrégé pom.xml
(celui contenant les sections
<modules>
) est situé dans un sous répertoire et non au niveau supérieur.
Le champ Properties vous permet de spécifier des valeurs de propriété qui seront passées au processus de build Maven, en utilisant le format standard de fichier illustré ici :
# Selenium test configuration selenium.host=testserver.acme.com selenium.port=8080 selenium.broswer=firefox
Ces propriétés sont passées à Maven en tant qu’options de ligne de commande, comme montré ici :
$ mvn verify -Dselenium.host=testserver.acme.com ...
Le champ JVM Options vous permet de spécifier des options standards de la machine virtuelle Java pour votre tâche de build.
Donc, si votre processus de build est particulièrement consommateur de mémoire, vous pourriez ajouter plus d’espace pour la
heap avec l’option -Xmx
(par exemple,
-Xmx512m
peut spécifier la taille maximum de la heap à 512 Mo).
La dernière option que vous pouvez configurer est un dépôt privé Maven pour cette tâche de build. Normalement, Maven utilisera le dépôt Maven par défaut (usuellement le dossier .m2/repository
dans le répertoire personnel de l’utilisateur). Parfois, cela peut mener à des interférences entre tâches de build, ou utiliser
des versions snapshot inconsistantes d’un build à un autre. Pour être sûr que votre build est lancé dans des conditions de
laboratoire, vous pouvez activer cette option. Votre tâche de build aura son propre dépôt privé, réservé pour son utilisation
exclusive. Sur le plan négatif, la première fois que la tâche de build lancera un build, cela prendra du temps pour télécharger
tous les artefacts Maven, et les dépôts privés peuvent prendre beaucoup de place. Cependant, c’est la meilleure façon de garantir
que votre build est lancé dans un environnement vraiment isolé.
Les tâches de build Freestyle fonctionnent également biens avec Ant. Apache Ant est un outil de scripting de build Java largement utilisé et bien connu. En effet, un nombre important de projets Java sont liés à des scripts de build Ant.
Ant n’est pas seulement utilisé comme un outil de build principal — même si votre projet utilise Maven, vous pouvez recourir à l’appel de scripts Ant pour faire des tâches spécifiques. Il y a des librairies Ant disponibles pour beaucoup d’outils de développement et des tâches bas niveau, comme utiliser SSH, ou travailler avec des serveurs d’application propriétaires.
Dans da forme la plus basique, configurer une étape de build Ant est très simple, en effet, il vous suffit de fournir la version de Ant que vous souhaitez utiliser et le nom de la target que vous voulez invoquer. Dans la Figure 5.27, “Configurer une étape de build Ant”, par exemple, nous invoquons un script Ant pour démarrer un script de test JMeter.
Comme dans une étape de build Maven, le bouton « Avancé… » vous fournit plus d’options détaillées, comme spécifier un script
de build different, ou un script de build dans un répertoire différent (celui par défaut sera build.xml
dans le répertoire racine).
Vous pouvez aussi spécifier des propriétés et des options de la JVM, comme vous pouvez le faire pour Maven.
Occasionnellement, vous pouvez avoir besoin d’exécuter une commande directement au niveau du système d’exploitation. Certains processus de build anciens sont liés à des scripts spécifiques à l’OS, par exemple. Dans d’autres cas, vous pourriez avoir besoin d’effectuer un opérateur bas niveau qui serait plus facilement faite avec une commande au niveau OS.
Vous pouvez faire ceci avec Jenkins avec une commande Exécuter un script shell
(pour Unix) ou Exécuter une ligne de commande batch Windows
(pour Windows). Par exemple, dans la Figure 5.28, “Configurer une étape Exécuter un script Shell”, nous avons ajouté une étape pour exécuter la commande Unix ls
.
La sortie de l’étape de build est montrée ici :
[workspace] $ /bin/sh -xe /var/folders/.../jenkins2542160238803334344.s + ls -al total 64 drwxr-xr-x 14 johnsmart staff 476 30 Oct 15:21 . drwxr-xr-x 9 johnsmart staff 306 30 Oct 15:21 .. -rw-r--r--@ 1 johnsmart staff 294 22 Sep 01:40 .checkstyle -rw-r--r--@ 1 johnsmart staff 651 22 Sep 01:40 .classpath -rw-r--r--@ 1 johnsmart staff 947 22 Sep 01:40 .project drwxr-xr-x 5 johnsmart staff 170 22 Sep 01:40 .settings -rw-r--r--@ 1 johnsmart staff 437 22 Sep 01:40 .springBeans drwxr-xr-x 9 johnsmart staff 306 30 Oct 15:21 .svn -rw-r--r--@ 1 johnsmart staff 1228 22 Sep 01:40 build.xml -rw-r--r--@ 1 johnsmart staff 50 22 Sep 01:40 infinitest.filters -rw-r--r-- 1 johnsmart staff 6112 30 Oct 15:21 pom.xml drwxr-xr-x 5 johnsmart staff 170 22 Sep 01:40 src drwxr-xr-x 3 johnsmart staff 102 22 Sep 01:40 target drwxr-xr-x 5 johnsmart staff 170 22 Sep 01:40 tools
Vous pouvez soit exécuter une commande spécifique à l’OS (ex : ls
), soit stocker un script plus compliqué comme un fichier dans votre gestionnaire de contrôle de version, et exécuter ce script.
Si vous exécutez un script, vous n’avez juste qu’à faire référence au nom de votre script relativement par rapport au répertoire
de travail.
Les scripts Shell sont exécutés en utilisant l’option -ex
— les commandes sont affichées dans la console, comme si c’était la sortie. Si n’importe laquelle des commandes exécutées
retourne une valeur différente de zéro, le build échouera.
Lorsque Jenkins exécute un script, il spécifie un nombre en tant que variable d’environnement que vous pouvez utiliser à l’intérieur de votre script. Nous discutons de ces variables plus en détail dans le prochaine section.
En réalité, il y a beaucoup de bonnes raisons pour lesquelles vous devriez éviter d’utiliser des scripts de niveau OS dans vos tâches de build si vous pouvez les éviter. En particulier, il rend votre tâche de build au meilleur des cas, spécifique à l’OS, et dans le pire dépendant de la configuration précise de la machine. Une alternative plus portable pour exécuter des scripts spécifiques à l’OS est d’écrire un script équivalent dans un langage de script plus portable, comme Groovy ou Gant.
Une astuce utile qui peut être utilisée dans pratiquement n’importe quelle étape de build est d’obtenir des informations de la part de Jenkins sur la tâche de build courante. En réalité, lorsque Jenkins démarre une étape de build, il met à disposition les variables d’environnement suivantes dans le script de build :
BUILD_NUMBER
Le numéro du build courant, comme “153”.
BUILD_ID
Un horodatage pour identifier le build courant, sous le format YYYY-MM-DD_hh-mm-ss.
JOB_NAME
Le nom du job, comme game-of-life.
BUILD_TAG
Un moyen commode d’identifier la tâche de build courante, sous la forme
jenkins-${
(ex :
JOB_NAME
}-${BUILD_NUMBER
}jenkins-game-of-life-2010-10-30_23-59-59
).
EXECUTOR_NUMBER
Un nombre identifiant l’exécuteur ayant démarré cette construction parmi les exécuteurs sur la même machine. C’est le nombre que vous voyez dans « Etat du lanceur de construction », à l’exception que ce nombre commence de 0, pas 1.
NODE_NAME
Le nom de l’esclave si ce build est en train d’être lancé sur un esclave, ou ""
si le build est en train d’être lancé sur le maître.
NODE_LABELS
La liste des libellés associés au nœud sur lequel le build est démarré.
JAVA_HOME
Si votre tâche est configurée pour utiliser une version spécifique de JDK, cette variable contient la valeur du JAVA_HOME
correspondant au JDK spécifié. Lorsque cette variable est fixée, la variable PATH
est aussi mise à jour pour avoir $JAVA_HOME/bin
.
WORKSPACE
Le chemin absolu du répertoire de travail.
HUDSON_URL
L’URL complète du serveur Jenkins, par exemple http://ci.acme.com:8080/jenkins/
.
JOB_URL
L’URL complète pour cette tâche de build, par exemple http://ci.acme.com:8080/jenkins/game-of-life
.
BUILD_URL
L’URL complète de ce build, par exemple http://ci.acme.com:8080/jenkins/game-of-life/20
.
SVN_REVISION
Pour les projets basés sur Subversion, cette variable contient le numéro de la révision courante.
CVS_BRANCH
Pour les projets basés sur CVS, cette variable contient la branche du module. Si CVS est configuré pour consulter le trunk, cette variable d’environnement ne sera pas spécifiée.
Ces variables sont faciles à utiliser. Dans un script Ant, vous pouvez y accéder avec le tag <property>
comme montré ici :
<target name="printinfo"> <property environment="env" /> <echo message="${env.BUILD_TAG}"/> </target>
Dans Maven, vous pouvez accéder au variables soit de la même manière (en utilisant le prefix « env. »), soit directement en utilisant
la variable d’environnement Jenkins. Par exemple, dans le fichier pom.xml, l’URL du projet pointera sur la tâche de build Jenkins qui a lancé le build mvn site
:
<project...> ... <groupId>com.wakaleo.gameoflife</groupId> <artifactId>gameoflife-core</artifactId> <version>0.0.55-SNAPSHOT</version> <name>gameoflife-core</name> <url>${JOB_URL}</url>
Alternativement, si vous construises une application web, vous pouvez aussi utiliser maven-war-plugin
pour insérer le numéro de la tâche de build dans le manifest de l’application web, ex :
<project> ... <build> ... <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <manifest> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> </manifest> <archive> <manifestEntries> <Specification-Title>Continuous Integration with Hudson (French Content)</Specification-Title> <Specification-Version>0.0.4-SNAPSHOT</Specification-Version> <Implementation-Version>${BUILD_TAG}</Implementation-Version> </manifestEntries> </archive> </configuration> </plugin> ... </plugins> </build> ... </project>
Cela produire un fichier MANIFEST.MF
avec les lignes suivantes :
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: johnsmart Build-Jdk: 1.6.0_22 Jenkins-Build-Number: 63 Jenkins-Project: game-of-life Jenkins-Version: 1.382 Implementation-Version: jenkins-game-of-life-63 Specification-Title: gameoflife-web Specification-Version: 0.0.55-SNAPSHOT
Dans un script Groovy, elles peuvent être accéder via la méthode
System.getenv()
:
def env = System.getenv() env.each { println it }
def env = System.getenv() println env['BUILD_NUMBER']
Groovy n’est pas seulement un langage dynamique populaire de la JVM, c’est aussi un langage qui convient pour le scripting de bas niveau. Le plugin Groovy de Jenkins vous permet d’exécuter des commandes Groovy arbitraires, ou invoquer des scripts Groovy, dans le cadre de votre processus de build.
Une fois que vous avez installé le plugin Groovy avec la manière habituelle, vous aurez besoin d’ajouter une référence de votre installation Groovy dans la page de configuration du système (voir la figure Figure 5.29, “Ajouter une installation Groovy à Jenkins”).
Maintenant, vous pouvez ajouter du script Groovy dans votre tâche de build. Lorsque vous cliquez sur ‘Ajouter une étape de build’, vous verrez deux nouvelles entrées dans le menu déroulant : « Exécuter un script Groovy » et « Exécuter un script Groovy Système ». La première option est généralement celle que vous souhaitez — cela exécutera simplement un script Groovy dans une JVM séparée, comme si vous l’invoquiez depuis la ligne de commande. La deuxième option lance des commandes Groovy depuis la JVM de Jenkins, avec un accès interne complet à Jenkins, et est principalement utilisé pour manipuler les tâches de build de Jenkins ou le processus de build lui-même. C’est un sujet plus avancé dont nous discuterons plus loin dans ce livre.
Une étape de build Groovy peut prendre une forme sur deux. Pour les cas simples, vous pouvez juste ajouter un petit bout de Groovy, comme montré dans la Figure 5.30, “Lancer des commandes Groovy dans le cadre d’une tâche de build”. Pour les cas plus complexes ou compliqués, vous pouvez probablement écrire un script Groovy et le placer sous un système de contrôle de version. Une fois que votre script est en sûreté dans votre SCM, vous pouvez le démarrer en sélectionnant l’option « Fichier de script Groovy » et fournir le chemin de votre script (relatif au répertoire de travail de la tâche de build).
Dans la Figure 5.31, “Lancer des scripts Groovy dans le cadre d’une tâche de build”, vous pouvez voir un exemple légèrement plus compliqué. Ici nous lançons un script Groovy appelé run-fitness-tests.groovy
, qui peut être trouvé dans le répertoire scripts
. Ce script prend des suites de test pour être exécutés comme ses paramètres — nous pouvons les mettre dans le champ Paramètres
Groovy. Sinon vous pouvez aussi fournir des propriétés en ligne de commande dans le champ Propriétés — c’est simplement un
moyen plus pratique d’utiliser l’option -D
en ligne de commande pour passer des valeurs de propriétés au script Groovy.
Jenkins est un outil flexible, il peut être utilisé avec beaucoup plus de de langage que Java et Groovy. Par exemple, Jenkins fonctionne aussi très bien avec Grails, .Net, Ruby, Python et PHP, juste pour en nommer quelques uns. En utilisant d’autres langages, vous aurez généralement besoin d’installer un plugin supportant votre langage favori, qui ajoutera un nouveau type d’étape de build pour ce langage.Nous regarderons d’autres exemples dans la section Section 5.10, “Utiliser Jenkins avec d’autres langages”.