Operations 25 min read

Master Jenkins Pipelines: Declarative vs Scripted Explained with Real Code

This article provides a comprehensive guide to Jenkins pipelines, covering the differences between declarative and scripted syntax, key directives, agents, stages, parallel execution, environment variables, credentials, and post‑processing steps, all illustrated with complete code examples.

Open Source Linux
Open Source Linux
Open Source Linux
Master Jenkins Pipelines: Declarative vs Scripted Explained with Real Code

What is a Jenkins Pipeline

Jenkins supports two types of pipelines: Declarative Pipeline (recommended for new versions) and Scripted Pipeline (used in older versions).

1.1 Declarative Pipeline

In Declarative syntax, the pipeline is defined inside a pipeline {} block. Core elements include:

agent any : run the pipeline on any available executor, or specify a particular node.

stage : defines a logical phase such as Build, Test, Deploy.

steps : the actual commands executed within a stage.

// Jenkinsfile (Declarative Pipeline)
pipeline {
  agent any
  stages {
    stage('Build') {
      steps { echo 'Build' }
    }
    stage('Test') {
      steps { echo 'Test' }
    }
    stage('Deploy') {
      steps { echo 'Deploy' }
    }
  }
}

1.2 Scripted Pipeline

Scripted pipelines use one or more node blocks to run core work.

// Jenkinsfile (Scripted Pipeline)
node {
  stage('Build') { echo 'Build' }
  stage('Test') { echo 'Test' }
  stage('Deploy') { echo 'Deploy' }
}

Declarative Pipeline Structure

A Declarative pipeline must contain a top‑level pipeline block. Inside, valid statements follow Groovy syntax with some exceptions.

The top level must be a pipeline{} block.

Semicolons are optional; each statement occupies its own line.

Blocks can contain Sections, Directives, Steps, or assignment statements.

Method‑like calls without parentheses (e.g., input) are treated as parameterless method calls.

Sections

Sections are code regions that may contain agent, stages, post, directives, and steps.

Agent

The agent defines where the pipeline or a specific stage runs.

any : any available executor.

none : no global agent; each stage must define its own.

label : run on a node with a specific label.

node : similar to label but allows extra configuration such as customWorkspace.

dockerfile and docker : run inside a Docker container built from a Dockerfile or an external image.

kubernetes : requires the Kubernetes plugin; enables dynamic agents using pod templates.

// Example of a Kubernetes agent
pipeline {
  agent none
  stages {
    stage('Example') {
      agent {
        kubernetes {
          cloud 'kubernetes'
          yaml '''
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
  - name: jnlp
    image: '192.168.10.15/kubernetes/jnlp:alpine'
''' 
        }
      }
      steps { echo 'Hello from Kubernetes' }
    }
  }
}

Post

The post block runs after a pipeline or stage finishes, handling outcomes such as always, failure, success, unstable, etc.

// Post example
pipeline {
  agent any
  stages {
    stage('Example1') { steps { echo 'Hello World1' } }
    stage('Example2') { steps { echo 'Hello World2' } }
  }
  post {
    always { echo 'I will always say Hello again!' }
  }
}

Steps

Steps execute commands within a stage, e.g., echo or sh scripts.

// Steps example
pipeline {
  agent any
  stages {
    stage('Example') {
      steps {
        echo 'Hello World'
        sh '''
          echo 'Line1'
          echo 'Line2'
        '''
      }
    }
  }
}

Directives

Directives provide additional configuration such as environment, options, parameters, triggers, input, and when.

Environment

Defines global or stage‑scoped variables, including credentials via the credentials() function.

// Global environment variable
pipeline {
  agent any
  environment { NAME = 'zhangzhuo' }
  stages {
    stage('env1') {
      environment { HARBOR = 'https://192.168.10.15' }
      steps { sh "env" }
    }
    stage('env2') { steps { sh "env" } }
  }
}

Options

Built‑in options like timeout, retry, timestamps, and quietPeriod control pipeline behavior.

// Options at pipeline level
pipeline {
  agent any
  options {
    timeout(time: 1, unit: 'HOURS')
    timestamps()
    buildDiscarder(logRotator(numToKeepStr: '3'))
    quietPeriod(10)
    retry(3)
  }
  stages { /* ... */ }
}

Parameters

Define user‑supplied inputs when triggering a build (e.g., string, booleanParam, choice, password).

// Parameter example
pipeline {
  agent any
  parameters {
    string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: 'Target environment')
    booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: 'Enable debug')
  }
  stages { /* ... */ }
}

Triggers

Automate pipeline execution via cron, upstream, or other mechanisms.

// Cron trigger example
pipeline {
  agent any
  triggers { cron('H */4 * * 1-5') }
  stages { /* ... */ }
}

Input

Interactive prompts that pause the pipeline for user confirmation.

// Input example
pipeline {
  agent any
  stages {
    stage('Deploy') {
      input {
        message "Proceed with deployment?"
        ok "Continue"
        submitter "alice,bob"
        parameters { string(name: 'PERSON', defaultValue: 'Mr Jenkins') }
      }
      steps { echo "Hello, ${PERSON}" }
    }
  }
}

When

Conditional execution of stages based on branch, environment, expression, etc.

// When example
pipeline {
  agent any
  stages {
    stage('Deploy') {
      when { branch 'main' }
      steps { echo 'Deploying' }
    }
  }
}

Parallel Execution

Parallel stages run concurrently, optionally using failFast to abort remaining branches on failure.

// Parallel example
pipeline {
  agent any
  stages {
    stage('Parallel') {
      failFast true
      parallel {
        stage('A') { steps { echo 'On Branch A' } }
        stage('B') { steps { echo 'On Branch B' } }
        stage('C') {
          stages {
            stage('Nested1') { steps { echo 'Nested 1' } }
            stage('Nested2') { steps { echo 'Nested 2' } }
          }
        }
      }
    }
  }
}

Using Jenkinsfile in Source Control

Storing the Jenkinsfile in a repository enables versioning, code review, and collaboration.

Environment Variables

Built‑in variables such as BUILD_ID, BUILD_NUMBER, BUILD_TAG, JOB_NAME, WORKSPACE, etc., are accessible via env.VAR_NAME.

Credentials Management

Credentials can be injected as secret text, username/password pairs, or secret files using the credentials() function.

// Secret text example
pipeline {
  agent any
  environment { AWS_ACCESS_KEY_ID = credentials('txt1') }
  stages { /* ... */ }
}
// Username/password example
pipeline {
  agent any
  environment { BITBUCKET_CREDS = credentials('harbor-account') }
  stages { /* ... */ }
}
Original article: https://zhangzhuo.ltd/articles/2022/06/04/1654333399919.html
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ci/cdDevOpsPipelineJenkinsDeclarativeScripted
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.