On Github thebignet / talk-jenkins-workflow
Passionné de nouvelles technologies
#jvm #docker #craftmanship #rpi #diy
Histoire de faire du déploiement continu
Le but du déploiement continu est d'avoir une application stable en production.
La chaine de livraison doit être automatisée au maximum pour réduire l'intervention humaine entre une modification de code et sa livraison en production.
L'erreur est humaine
Ce n'est pas le but premier du déploiement continu.
Pouvoir livrer rapidement ne veut pas dire livrer régulièrement.
Fichier de build en Groovy
Du build au deploy dans un fichier compréhensible
Permet une orchestration plus avancée
Convention de nommage : Jenkinsfile
node { git url: 'https://github.com/spring-projects/spring-petclinic.git' def mvnHome = tool 'M3' sh "${mvnHome}/bin/mvn -B verify" }
node { git url: 'https://github.com/spring-projects/spring-petclinic.git' def mvnHome = tool 'M3' sh "${mvnHome}/bin/mvn -B verify" }
sh 'ls /tmp'
bat 'dir C:\tmp'
Pour reprendre un script standard, il suffit de reprendre toutes les lignes du script comme ceci
echo 'Compilation'
try { checkpoint('Before production') } catch (NoSuchMethodError _) { echo 'Checkpoint feature available in CloudBees Jenkins Enterprise.' }
files.each{ file -> sh "check.sh $file" }
for num in 1..10 sh "echo $num" }
def mvn(args) { sh "${tool 'Maven 3.x'}/bin/mvn ${args}" } mvn 'clean install'
input 'Est-ce que la page ${url} est correcte ?'
Si cette validation intervient avant le déploiement, on fait de la livraison continue
node('unix && 64bit') { sh 'make install' }
Shell
$VAR
Groovy
env.VAR
for (int i = 0; i < splits.size(); i++) { branches["split${i}"] = { node('remote') { sh 'rm -rf *' sh "${tool 'M3'}/bin/mvn -B -Dmaven.test.failure.ignore test" } } } parallel branches
stage 'build' sh "${tool 'M3'}/bin/mvn clean install" stage concurrency: 1, name: 'deploy' sh 'mv target/app.war /tmp/webapps/'
stage 'build' sh "${tool 'M3'}/bin/mvn clean install" stage name: 'deploy', concurrency: 1 sh 'mv target/app.war /tmp'
node{ def install = load 'install.groovy' install.main() }
Permet de diviser le script de build en plusieurs parties
Liens pour afficher les logs de chaque étape
Jenkins a uniquement besoin de connaître l'URL du repository
Pour chaque branche à la racine de ce repository doit se trouver le fichier Jenkinsfile
Les branches sont scrutées régulièrement et mises à jour et lancées
On peut utiliser un hook pour lancer les builds
Besoin d'installer des outils
Le bon JDK, la version de Maven qu'il me faut, gradle ? sbt ? compilateur ?
Docker est la solution à tout de toutes manières
docker.image('maven:3.3.3-jdk-8').inside { sh 'mvn -B clean install' }
Le répertoire courant dans docker est le workspace Jenkins
Montage du workspace dans un volume docker
Plus de problèmes d'outils, mis à part Docker qui doit être installé sur les slaves
Le container est supprimé après son exécution
node { git scm // Récupérer le repository git en mode multibranch def myEnv = docker.build 'my-environment:snapshot' myEnv.push() }
node { git scm // Récupérer le repository git en mode multibranch def myEnv = docker.build "my-environment:${env.BUILD_TAG}" myEnv.push() }
Utilisation du tag git pour pousser dans le registry
node { git scm docker.image('mysql').withRun('-p 81:3126') {c -> sh './test-with-local-db' } }
On veut exécuter le corps du withRun alors que l'image mysql tourne
Le withRun prend optionnellement les paramètres du docker run
Adapté aux tests d'intégration
node { docker.withRegistry('https://docker.mycorp.com/', 'docker-login'){ git scm docker.build('myapp').push('latest') } }
Possibilité d'utiliser un registry privé
On passe des credentials enregistrés dans Jenkins
docker.withServer('tcp://swarm.mycorp.com:2376', 'swarm-certs'){ docker.image('httpd').withRun('-p 8080:80') {c -> sh "curl -i http://${hostIp(c)}:8080/" } } def hostIp(container) { sh "docker inspect -f {{.Node.Ip}} ${container.id} > hostIp" readFile('hostIp').trim() }
Possibilité de déléguer à un serveur docker (swarm ou autre)
Le client docker doit être installé
A utiliser si le slave ne peut pas supporter l'application à tester