Skip to main content

Jenkins Pipelines


Introduction to Pipelines

A Jenkins pipeline is a series of automated steps defined in Groovy code.


Declarative vs Scripted Pipeline

Predefined structure, simpler to learn.

pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}

Scripted

More flexible, pure Groovy syntax.

node {
stage('Build') {
sh 'mvn clean package'
}
}

Comparison

AspectDeclarativeScripted
SyntaxStructuredFree-form
FlexibilityMediumHigh
ValidationAt write timeAt runtime
Learning curveEasyMedium
Recommended✅ YesFor complex cases

Structure of a Declarative Pipeline

pipeline {
// Où exécuter le pipeline
agent any

// Variables d'environnement
environment {
APP_NAME = 'my-app'
VERSION = '1.0.0'
}

// Options globales
options {
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '10'))
}

// Paramètres d'entrée
parameters {
string(name: 'BRANCH', defaultValue: 'main')
choice(name: 'ENV', choices: ['dev', 'prod'])
}

// Déclencheurs
triggers {
pollSCM('H/5 * * * *')
}

// Étapes du pipeline
stages {
stage('Build') {
steps {
sh 'echo "Building ${APP_NAME}"'
}
}

stage('Test') {
steps {
sh 'npm test'
}
}

stage('Deploy') {
steps {
sh 'kubectl apply -f k8s/'
}
}
}

// Actions post-pipeline
post {
always {
cleanWs()
}
success {
slackSend message: "Build réussi!"
}
failure {
mail to: '[email protected]',
subject: "Build échoué: ${JOB_NAME}",
body: "Vérifier: ${BUILD_URL}"
}
}
}

Agent

The agent defines where the pipeline runs.

Agent types

// N'importe quel agent disponible
agent any

// Pas d'agent (pour stages individuels)
agent none

// Agent avec label spécifique
agent {
label 'linux'
}

// Agent Docker
agent {
docker {
image 'node:18'
args '-v /tmp:/tmp'
}
}

// Agent Kubernetes
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8-openjdk-17
command: ['sleep', 'infinity']
'''
}
}

// Dockerfile dans le repo
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'docker'
args '-v /tmp:/tmp'
}
}

Agent per stage

pipeline {
agent none

stages {
stage('Build') {
agent {
docker { image 'maven:3.8' }
}
steps {
sh 'mvn clean package'
}
}

stage('Test') {
agent {
docker { image 'node:18' }
}
steps {
sh 'npm test'
}
}

stage('Deploy') {
agent {
label 'kubernetes'
}
steps {
sh 'kubectl apply -f k8s/'
}
}
}
}

Stages and Steps

Stage

A stage is a logical phase of the pipeline.

stages {
stage('Checkout') {
steps {
checkout scm
}
}

stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}

stage('Unit Tests') {
steps {
sh 'mvn test'
}
}

stage('Integration Tests') {
steps {
sh 'mvn verify -Pintegration'
}
}

stage('Deploy') {
steps {
sh './deploy.sh'
}
}
}

Common steps

steps {
// Exécuter un script shell
sh 'echo "Hello"'
sh '''
echo "Multi-line"
echo "Script"
'''

// Windows batch
bat 'echo Hello'

// PowerShell
powershell 'Write-Host "Hello"'

// Checkout Git
checkout scm
git branch: 'main', url: 'https://github.com/user/repo.git'

// Afficher un message
echo 'Building...'

// Archiver des artifacts
archiveArtifacts artifacts: 'target/*.jar'

// Publier les résultats de tests
junit 'target/surefire-reports/*.xml'

// Envoyer un email
mail to: '[email protected]',
subject: 'Build',
body: 'Done'

// Slack
slackSend channel: '#builds',
message: "Build ${BUILD_NUMBER} terminé"

// Attendre une approbation
input message: 'Déployer en production?'

// Définir une variable
script {
env.MY_VAR = 'value'
}
}

Parallelization

Parallel stages

pipeline {
agent any

stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}

stage('Tests') {
parallel {
stage('Unit Tests') {
steps {
sh 'mvn test'
}
}
stage('Integration Tests') {
steps {
sh 'mvn verify'
}
}
stage('E2E Tests') {
agent {
docker { image 'cypress/included' }
}
steps {
sh 'cypress run'
}
}
}
}

stage('Deploy') {
steps {
sh 'kubectl apply -f k8s/'
}
}
}
}

Matrix

pipeline {
agent none

stages {
stage('Test Matrix') {
matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows', 'mac'
}
axis {
name 'NODE_VERSION'
values '16', '18', '20'
}
}

excludes {
exclude {
axis {
name 'PLATFORM'
values 'mac'
}
axis {
name 'NODE_VERSION'
values '16'
}
}
}

stages {
stage('Test') {
agent {
label "${PLATFORM}"
}
steps {
sh "nvm use ${NODE_VERSION} && npm test"
}
}
}
}
}
}
}

Conditions

When

stages {
stage('Build') {
steps {
sh 'mvn package'
}
}

stage('Deploy to Dev') {
when {
branch 'develop'
}
steps {
sh 'kubectl apply -f k8s/dev/'
}
}

stage('Deploy to Prod') {
when {
allOf {
branch 'main'
environment name: 'DEPLOY', value: 'true'
}
}
steps {
sh 'kubectl apply -f k8s/prod/'
}
}

stage('Nightly Build') {
when {
triggeredBy 'TimerTrigger'
}
steps {
sh 'mvn clean install'
}
}

stage('PR Build') {
when {
changeRequest()
}
steps {
sh 'mvn verify'
}
}
}

Available conditions

when {
// Branche spécifique
branch 'main'
branch pattern: 'release-*', comparator: 'GLOB'

// Tag
tag 'v*'

// Environnement
environment name: 'ENV', value: 'prod'

// Expression Groovy
expression { return params.DEPLOY == true }

// Fichier modifié
changeset '**/*.java'

// Pull Request
changeRequest()
changeRequest target: 'main'

// Combinaisons
allOf {
branch 'main'
environment name: 'DEPLOY', value: 'true'
}

anyOf {
branch 'main'
branch 'develop'
}

not {
branch 'feature/*'
}
}

Error handling

Try-Catch

pipeline {
agent any

stages {
stage('Deploy') {
steps {
script {
try {
sh 'kubectl apply -f k8s/'
} catch (Exception e) {
echo "Deployment failed: ${e.message}"
sh 'kubectl rollback'
throw e
}
}
}
}
}
}

catchError

stage('Tests') {
steps {
catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') {
sh 'npm test'
}
}
}

Retry and Timeout

stage('Deploy') {
steps {
retry(3) {
timeout(time: 5, unit: 'MINUTES') {
sh 'kubectl apply -f k8s/'
}
}
}
}

Post Actions

pipeline {
agent any

stages {
stage('Build') {
steps {
sh 'mvn package'
}
}
}

post {
// Toujours exécuté
always {
junit 'target/surefire-reports/*.xml'
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
cleanWs()
}

// Si succès
success {
slackSend color: 'good', message: "Build #${BUILD_NUMBER} réussi"
}

// Si échec
failure {
slackSend color: 'danger', message: "Build #${BUILD_NUMBER} échoué"
mail to: '[email protected]',
subject: "FAILED: ${JOB_NAME} #${BUILD_NUMBER}",
body: "Check: ${BUILD_URL}"
}

// Si instable (tests échoués)
unstable {
slackSend color: 'warning', message: "Build instable"
}

// Si changement de statut
changed {
echo 'Le statut du build a changé'
}

// Si revenu à la normale
fixed {
slackSend color: 'good', message: "Build réparé!"
}

// Si annulé
aborted {
echo 'Build annulé'
}
}
}

Summary

ConceptDescription
PipelineCI/CD workflow as code
DeclarativeStructured syntax (recommended)
ScriptedPure Groovy (flexible)
StageLogical phase
StepSingle action
AgentWhere the build runs
WhenExecution conditions
PostPost-build actions

← Interface and Jobs | Jenkinsfile →