Scripted pipelines and the script block

Jenkins · Advanced · 12 min

Many existing Jenkinsfiles are scripted, and real pipelines eventually need loops or dynamic stages.

Before declarative syntax, pipelines were written as scripted pipelines: plain Groovy built from steps like node, stage, checkout scm and parallel. There is no fixed structure, no post or when; you use try/catch/finally and if instead.

node('linux') {
    stage('Build') { checkout scm; sh 'make' }
}

node allocates an executor and workspace; everything inside runs there.

Declarative pipelines can drop into Groovy with script { } inside steps. Use it for small logic: reading a file with readFile, looping to build a map of parallel branches, or setting a variable for later stages. If script blocks grow large, move the logic into a shared library.

Pipeline Groovy is not normal Groovy. Scripts run in the Groovy sandbox: unapproved method calls fail with RejectedAccessException until an administrator approves them under In-process Script Approval. And code is transformed for durability (the next lesson), so a few Groovy features, such as some closure-taking methods like sort with a comparator closure, behave differently or fail. Steps like readJSON, readYaml and writeFile (Pipeline Utility Steps plugin) are safer than raw Java APIs.

Example

pipeline {
    agent any
    stages {
        stage('Dynamic tests') {
            steps {
                script {
                    def suites = ['api', 'web', 'worker']
                    def branches = [:]
                    for (s in suites) {
                        def suite = s                       // capture per iteration
                        branches[suite] = { sh "make test-${suite}" }
                    }
                    parallel branches                       // 3 parallel branches
                    env.TESTED = suites.join(',')
                }
                echo "Tested: ${env.TESTED}"               // Tested: api,web,worker
            }
        }
    }
}

Remember

  • Scripted pipelines use node/stage/try-catch instead of declarative blocks
  • script { } embeds Groovy logic in declarative pipelines
  • Pipeline Groovy runs in a sandbox with approvals and CPS transformation

Watch out for

  • Capturing a loop variable directly in closures, so every branch sees the last value; copy it per iteration.

Check yourself

  1. A pipeline fails with RejectedAccessException. What does it mean?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.jenkins.io/doc/book/pipeline/syntax/#scripted-pipeline