Jenkins est depuis plusieurs années l’outil d’intégration continue le plus répandu quelque soit le type de projet informatique.
Plus récemment, le plugin Blue Ocean est passé de version beta à la version 1, offrant une interface beaucoup plus user-friendly, et la mise en avant des jobs de type Pipeline (versus les jobs de type Freestyle).
Job Freestyle
Pour ceux qui souhaitent utiliser Jenkins en mode Freestyle au sein d’un projet PHP, Sebastian Bergmann (créateur de PHPUnit) met à disposition un template réutilisable qui permet d’avoir les étapes du build pré-paramétrées (vérification de code, tests unitaires) : voir le site dédié.
Pipeline
Ce type de job permet de définir un enchaînement de tâches complexes.
Il est possible de créer un Pipeline depuis un fichier Jenkinsfile déposé à la racine du projet versionné, ou depuis l’interface de Jenkins : « New Item > Pipeline ».
Le fichier peut être nommé différemment mais il faudra préciser le nouveau nom à Jenkins, exemple : Jenkinsfile.groovy (pour avoir la coloration syntaxique).
Vidéo explicative
Exécuter le Pipeline automatiquement
Il est intéressant d’utiliser un webhook afin que votre VCS trigger l’éxecution du Pipeline suite à une modification de code.
C’est plus performant que de demander à Jenkins de scruter un dépôt Git toutes les minutes.
Syntaxe
La syntaxe est assez clair et compréhensible, certaines directives sont présentes sh
, git
, echo
, il est possible de définir des variables def myVar
, ou encore d’utiliser un try/catch/finally
.
Certaines fonctions spécifiques existent également comme : slackSend
(envoi un message dans un channel Slack) ou encore updateGitlabCommitStatus
(modifie le statut du Pipeline associé au commit dans GitLab).
La variable currentBuild.result
peut être assigné tout au long du Pipeline (SUCCESS, FAILURE etc.) afin de changer le statut du build.
Il est intéressant de pouvoir placer les instructions dans des stage différents pour séparer les grandes étapes, et d’en exécuter en parallel pour gagner du temps.
Exemple de Jenkinsfile
#!groovy
node {
currentBuild.result = "SUCCESS"
try {
stage('Init') {
git branch: 'develop', credentialsId: 'xxxxxxxxxxx', url: 'git@vcs.my.company:repo.git'
sh "bash ./bin/init.sh ${env.WORKSPACE}"
}
stage('Tests Back') {
parallel (
PHPCs: { sh "phpcs --standard=PSR2 --extensions=php" },
PHPUnit: { ${env.WORKSPACE}/vendor/bin/phpunit },
PHPLint: { ${env.WORKSPACE}/vendor/bin/phplint },
PHPMD: { ${env.WORKSPACE}/vendor/bin/phpmd },
Behat: { ${env.WORKSPACE}/vendor/bin/behat }
)
}
stage('Tests Front') {
parallel (
Sass: { sh "yarn sasslint" },
JS: { sh "yarn eslint" }
)
}
stage('End') {
parallel (
Slack: { slackSend color: 'good', message: "${env.JOB_NAME} [${env.BUILD_NUMBER}]: Successful (${env.BUILD_URL})" },
GitLab: { updateGitlabCommitStatus(name: 'build', state: 'success') }
)
}
} catch (err) {
currentBuild.result = "FAILURE"
slackSend color: 'danger', message: "${env.JOB_NAME} [${env.BUILD_NUMBER}]: Failed (${env.BUILD_URL})"
updateGitlabCommitStatus(name: 'build', state: 'failed')
throw err
} finally {
sh 'do some other stuff'
}
}
Exemple de résultat
Événement autour de Jenkins en France
Nice, octobre 2018 : https://www.cloudbees.com/devops-world/nice