Jenkins Pipelines with Groovy

42.1 Declarative Pipeline

// Jenkinsfile
pipeline {
    agent any
    environment {
        APP_ENV = 'staging'
        CREDS = credentials('deploy-token')
    }
    options { timeout(time: 30, unit: 'MINUTES'); buildDiscarder(logRotator(numToKeepStr: '10')) }
    parameters { choice(name: 'TARGET', choices: ['dev', 'prod'], description: 'Deploy target') }
    triggers { cron('H 2 * * *') }

    stages {
        stage('Checkout') { steps { checkout scm } }
        stage('Build') { steps { sh './gradlew build' } }
        stage('Test') {
            parallel {
                stage('Unit') { steps { sh './gradlew test' } }
                stage('Lint') { steps { sh './gradlew codenarcMain' } }
            }
            post { always { junit '**/build/test-results/**/*.xml' } }
        }
        stage('Deploy') {
            when { branch 'main'; expression { params.TARGET == 'prod' } }
            steps {
                input message: 'Deploy to prod?'
                script {
                    def version = readFile('VERSION').trim()
                    echo "Deploying ${version}"
                }
            }
        }
    }
    post {
        success { echo 'Done!' }
        failure { mail to: 'team@
…

42.2 Scripted Pipeline

node('linux') {
    stage('Build') {
        try {
            checkout scm
            def mvnHome = tool 'maven-3'
            sh "${mvnHome}/bin/mvn -B package"
        } catch (err) {
            currentBuild.result = 'FAILURE'
            throw err
        } finally {
            archiveArtifacts artifacts: 'target/*.jar', allowEmptyArchive: true
        }
    }
}

42.3 Shared Libraries

(shared-lib repo)
├── vars/
│   └── deployApp.groovy        // global step: deployApp(env: 'prod')
├── src/com/example/Utils.groovy
└── resources/templates/config.yaml
// vars/deployApp.groovy
def call(Map cfg = [:]) {
    echo "Deploying to ${cfg.env ?: 'dev'}"
    sh "kubectl apply -f k8s/${cfg.env}.yaml"
}
// Jenkinsfile
@Library('my-shared-lib@main') _
deployApp(env: 'prod')

42.4 Jenkins Groovy Caveats

Pipelines run in the CPS (Continuation-Passing Style) interpreter, so state is serialized for resumability. Some Groovy features behave differently: closures in collect/each can be problematic, and non-serializable objects need @NonCPS methods.

Script Security sandbox: many methods need administrator approval. Avoid heavy logic in Jenkinsfiles and move it to shared libraries or external scripts.

Also: the Script Console (Manage Jenkins → Script Console) for admin automation, Jenkins.instance APIs, Job DSL plugin (Groovy DSL to generate jobs), JCasC (Configuration as Code, YAML).