Les Shared Libraries permettent de factoriser la logique commune entre plusieurs Jenkinsfiles (fonctions de déploiement, notifications, helpers Docker…). Elles sont versionnées dans un dépôt Git dédié.


Structure d’une Shared Library

jenkins-shared-library/        ← dépôt Git dédié
├── vars/                      ← fonctions globales appelables directement dans les Jenkinsfiles
│   ├── deployApp.groovy       → deployApp(...)
│   ├── notifySlack.groovy     → notifySlack(...)
│   └── dockerBuild.groovy     → dockerBuild(...)
├── src/                       ← classes Groovy (logique plus complexe)
│   └── com/monorg/
│       ├── Docker.groovy
│       └── Notifier.groovy
└── resources/                 ← fichiers statiques (scripts shell, templates YAML)
    └── scripts/
        └── deploy.sh

Déclarer la library dans Jenkins

Manage Jenkins → Configure System → Global Pipeline Libraries
  ├── Name            : monorg-shared-lib
  ├── Default version : main
  ├── Retrieval method: Modern SCM → Git
  └── URL             : https://github.com/monorg/jenkins-shared-library.git

Utiliser la library dans un Jenkinsfile

// Chargement implicite (configuré en "implicit load" dans Jenkins)
@Library('monorg-shared-lib') _
 
// Chargement explicite avec version spécifique
@Library('monorg-shared-lib@v1.2.0') _
 
// Chargement de plusieurs libraries
@Library(['monorg-shared-lib', 'autre-lib@main']) _

Créer une fonction dans vars/

Chaque fichier vars/maFonction.groovy expose une fonction call() :

// vars/deployApp.groovy
def call(Map config = [:]) {
    def env     = config.env     ?: 'dev'
    def version = config.version ?: env.BUILD_NUMBER
 
    echo "Déploiement de la version ${version} en ${env}"
 
    sh """
        kubectl set image deployment/${config.app} \
            app=${config.registry}/${config.app}:${version} \
            --namespace=${env}
        kubectl rollout status deployment/${config.app} --namespace=${env}
    """
}

Utilisation dans un Jenkinsfile :

@Library('monorg-shared-lib') _
 
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                deployApp(
                    app      : 'mon-api',
                    env      : params.ENV,
                    registry : 'registry.example.com',
                    version  : env.BUILD_NUMBER
                )
            }
        }
    }
}

Créer une classe dans src/

Pour la logique plus complexe avec état :

// src/com/monorg/Notifier.groovy
package com.monorg
 
class Notifier implements Serializable {
    def steps
    String channel
 
    Notifier(steps, String channel) {
        this.steps   = steps
        this.channel = channel
    }
 
    def success(String message) {
        steps.slackSend channel: channel, color: 'good', message: "✅ ${message}"
    }
 
    def failure(String message) {
        steps.slackSend channel: channel, color: 'danger', message: "❌ ${message}"
    }
}

Utilisation :

@Library('monorg-shared-lib') _
import com.monorg.Notifier
 
pipeline {
    agent any
    stages {
        stage('Build') {
            steps { sh 'mvn package' }
        }
    }
    post {
        success {
            script {
                def n = new Notifier(this, '#ci-cd')
                n.success("Build ${env.BUILD_NUMBER} réussi")
            }
        }
    }
}

Accéder aux ressources statiques

// Dans vars/deployApp.groovy
def call(String env) {
    def script = libraryResource 'scripts/deploy.sh'
    writeFile file: 'deploy.sh', text: script
    sh 'chmod +x deploy.sh && ./deploy.sh ' + env
}

Bonnes pratiques

PratiqueRaison
Versionner avec des tags (v1.0.0)Reproductibilité — un Jenkinsfile pointe vers une version stable
Implémenter Serializable sur les classesÉvite les erreurs de sérialisation en cas de pause du pipeline
Documenter avec vars/maFonction.txtGénère la documentation dans l’UI Jenkins
Tester avec JenkinsPipelineUnitFramework de tests unitaires pour les Shared Libraries
Limiter les droits de la libraryConfigurer en “Trusted” uniquement pour les libs validées

En relation avec