Contactez-nous

Eléments clés d'un Pipeline : agent, stages, steps (ex: sh, git)

Comprenez les piliers d'un Pipeline Jenkins Déclaratif : l'agent (où ?), les stages (quoi ?) et les steps (comment ?), illustrés avec les commandes sh et git.

Les piliers d'un Pipeline Jenkins Déclaratif : agent, stages, et steps

Pour construire des Pipelines Jenkins efficaces en utilisant la syntaxe Déclarative, il est crucial de bien comprendre ses composants fondamentaux. Ces éléments structurent votre `Jenkinsfile` et définissent comment et où votre processus d'automatisation va s'exécuter. Les trois piliers que nous allons explorer sont : l'agent, les stages, et les steps. Maîtriser leur rôle et leur interaction est la clé pour écrire des pipelines clairs, robustes et maintenables.

Imaginez que vous organisez un grand projet. L'agent serait le lieu ou l'équipe qui va réaliser le travail. Les stages seraient les grandes phases de votre projet (conception, développement, test, livraison). Et les steps seraient les tâches spécifiques à accomplir à l'intérieur de chaque phase. Jenkins utilise cette analogie pour orchestrer vos workflows CI/CD.

Nous allons détailler chacun de ces éléments, en illustrant leur utilisation avec des exemples concrets, notamment l'exécution de commandes shell (sh) et l'interaction avec Git (git), qui sont des opérations courantes dans la plupart des pipelines.

L'agent : où s'exécute votre Pipeline ?

La directive agent est fondamentale car elle spécifie l'environnement d'exécution de votre pipeline, ou d'une partie de celui-ci. Jenkins peut fonctionner avec une architecture distribuée, où un master Jenkins orchestre des builds qui s'exécutent sur différents noeuds appelés agents (anciennement "slaves"). L'agent définit quel type de noeud ou quel environnement spécifique est requis.

Voici les syntaxes les plus courantes pour la directive agent :

  • agent any :
    C'est la forme la plus simple. Elle indique que le pipeline (ou le stage) peut s'exécuter sur n'importe quel agent disponible configuré dans Jenkins. C'est souvent utilisé pour des tâches simples ou lorsque l'environnement spécifique importe peu.
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Running on any available agent.'
                }
            }
        }
    }
  • agent none :
    Utilisé au niveau supérieur du bloc pipeline, cela signifie qu'il n'y a pas d'agent global pour l'ensemble du pipeline. Chaque stage devra alors définir son propre agent. C'est utile pour les pipelines qui nécessitent des environnements différents pour des étapes distinctes.
    pipeline {
        agent none
        stages {
            stage('Build on Linux') {
                agent { label 'linux-builder' }
                steps {
                    echo 'Building on a Linux agent...'
                }
            }
            stage('Test on Windows') {
                agent { label 'windows-tester' }
                steps {
                    echo 'Testing on a Windows agent...'
                }
            }
        }
    }
  • agent { label 'mon-etiquette' } :
    Spécifie que le pipeline ou le stage doit s'exécuter sur un agent possédant l'étiquette (label) 'mon-etiquette'. Les administrateurs Jenkins attribuent des étiquettes aux agents pour les caractériser (ex: 'linux', 'windows', 'docker-capable', 'jdk11').
    agent { label 'jdk11-and-maven' }
  • agent { node { label 'mon-etiquette'; customWorkspace '/mnt/jenkins_ws' } } :
    Offre plus de contrôle, comme la spécification d'un répertoire de travail personnalisé (customWorkspace) sur l'agent.
    agent {
        node {
            label 'build-node'
            customWorkspace "/opt/jenkins/workspace/${env.JOB_NAME}/${env.BUILD_NUMBER}"
        }
    }
  • agent { docker 'image:tag' } ou agent { dockerfile true } :
    Permet d'exécuter le pipeline ou le stage à l'intérieur d'un conteneur Docker. docker 'image:tag' utilise une image Docker existante depuis un registre (comme Docker Hub). dockerfile true indique à Jenkins de construire une image à partir d'un `Dockerfile` présent dans le répertoire source de votre projet, puis d'exécuter le pipeline/stage dans un conteneur basé sur cette image. C'est extrêmement puissant pour créer des environnements de build reproductibles et isolés.
    // Utiliser une image pré-existante
    agent { docker 'maven:3.8.4-openjdk-11' }
    
    // Construire depuis un Dockerfile local
    // (nécessite un fichier 'Dockerfile' à la racine du projet)
    agent { dockerfile true }
    D'autres options pour Docker existent, comme args pour passer des arguments au conteneur Docker, alwaysPull pour toujours tirer l'image, etc.

Le choix de l'agent est crucial car il détermine la disponibilité des outils (compilateurs, interpréteurs, etc.) et l'environnement (système d'exploitation) dans lequel vos commandes s'exécuteront.

Les stages : structurer votre Workflow

La directive stages est une section obligatoire qui contient une ou plusieurs directives stage. Chaque stage représente une phase distincte de votre pipeline CI/CD. C'est une manière de regrouper logiquement un ensemble d'opérations. Par exemple, des étapes classiques sont : "Checkout", "Build", "Test", "Code Analysis", "Deploy to Staging", "Approve Deployment", "Deploy to Production".

La syntaxe d'un stage est simple :

pipeline {
    agent any
    stages {
        stage('Nom du Stage 1') { // Le nom doit être unique et descriptif
            // Ce stage peut avoir son propre 'agent', 'environment', 'tools', 'options', 'when', 'post', etc.
            steps {
                // Les actions de ce stage
                echo 'Actions du Stage 1'
            }
        }
        stage('Nom du Stage 2') {
            steps {
                echo 'Actions du Stage 2'
            }
        }
        // ... autres stages
    }
}

Les stages sont exécutés séquentiellement par défaut. Ils sont visualisés clairement dans l'interface Jenkins (notamment dans Blue Ocean ou la Stage View), ce qui permet de suivre facilement la progression du pipeline et d'identifier rapidement quelle phase a échoué le cas échéant.

Chaque stage est un bloc qui peut contenir ses propres directives agent (pour s'exécuter sur un environnement différent du reste du pipeline), environment (variables d'environnement spécifiques), tools, options, et surtout une directive steps.

Les steps : les actions concrètes de votre Pipeline

La directive steps est définie à l'intérieur d'un stage et contient la séquence des actions (ou "pas") à exécuter pour ce stage. C'est ici que le travail réel est effectué. Un step peut être une simple commande, l'invocation d'un script, ou l'utilisation d'une fonctionnalité offerte par un plugin Jenkins.

Jenkins fournit un grand nombre de steps intégrés ou via des plugins. Voici quelques exemples courants :

  • sh 'commande' : Exécute une commande shell (sur les systèmes Unix/Linux). Pour Windows, l'équivalent est bat 'commande'.
    steps {
        sh 'echo "Hello from shell"'
        sh 'mvn clean package -DskipTests'
        sh '''
            echo "Multi-ligne"
            ls -l
        ''' // Pour les scripts multi-lignes
    }
  • git : Permet d'interagir avec des dépôts Git. Bien que le checkout initial soit souvent géré par la configuration SCM du job Pipeline, ce step peut être utilisé pour des opérations Git supplémentaires (taguer, pusher des modifications, etc.).
    steps {
        // Exemple de checkout explicite (si non géré par le SCM du job)
        git url: 'https://github.com/votre-utilisateur/votre-projet.git', branch: 'main'
    
        // Exemple pour taguer et pusher (nécessite des credentials configurés)
        // sh 'git tag v1.0.0'
        // withCredentials([usernamePassword(credentialsId: 'git-credentials', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
        //    sh 'git push --tags origin'
        // }
    }
    Le step checkout scm est plus couramment utilisé pour récupérer le code source défini dans la configuration SCM du job Pipeline :
    steps {
        checkout scm
        echo 'Code source récupéré.'
    }
  • echo 'message' : Affiche un message dans la sortie console du build. Très utile pour le débogage et le suivi.
    steps {
        echo "Début de l'étape de build."
    }
  • error 'message' : Arrête le pipeline et marque le build comme échoué, avec le message spécifié.
    steps {
        script {
            def version = readFile 'version.txt'
            if (version ==~ /^\d+\.\d+\.\d+$/) {
                echo "Version valide: ${version}"
            } else {
                error "Format de version invalide: ${version}"
            }
        }
    }
  • stash / unstash : Permet de sauvegarder temporairement des fichiers (stash) dans une étape pour les réutiliser plus tard dans une autre étape (unstash), potentiellement sur un autre agent. Utile pour passer des artefacts de build entre des stages qui s'exécutent sur des agents différents sans utiliser un gestionnaire d'artefacts externe pour des besoins simples.
    stage('Build') {
        agent { label 'builder' }
        steps {
            sh './build.sh'
            stash name: 'app-binaries', includes: 'target/*.jar'
        }
    }
    stage('Deploy') {
        agent { label 'deployer' }
        steps {
            unstash 'app-binaries'
            sh 'java -jar target/mon-app.jar'
        }
    }
  • dir('nom-repertoire') { ... } : Exécute les steps contenus à l'intérieur du bloc dans un sous-répertoire spécifié de l'espace de travail.
    steps {
        dir('backend') {
            sh 'npm install'
        }
        dir('frontend') {
            sh 'yarn install'
        }
    }
  • De nombreux autres steps sont disponibles via les plugins : junit (pour les rapports de test), archiveArtifacts (pour archiver les fichiers générés), build (pour déclencher d'autres jobs Jenkins), input (pour demander une confirmation manuelle), etc.

La combinaison judicieuse de agent, stages, et steps (comme sh pour les commandes systèmes ou git pour le SCM) vous permet de construire des pipelines Déclaratifs puissants et bien structurés pour automatiser l'ensemble de votre cycle de livraison logicielle.