Operations 26 min read

Mastering Jenkins Pipelines: Declarative vs Scripted with Real‑World Examples

This article provides a comprehensive guide to Jenkins pipelines, explaining the difference between declarative and scripted syntax, detailing agent configurations, workspace volumes, post actions, directives, environment variables, dynamic variables, credential handling, and practical Jenkinsfile examples for CI/CD automation.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Mastering Jenkins Pipelines: Declarative vs Scripted with Real‑World Examples

What Is a Jenkins Pipeline

Jenkins supports two types of pipelines: Declarative Pipeline and Scripted Pipeline. Declarative pipelines are the recommended modern syntax, while scripted pipelines are the older Groovy‑based approach.

Declarative Pipeline

In a declarative pipeline the entire workflow is defined inside a pipeline{} block. Key sections include agent, stages, steps, post, and optional directives.

pipeline {
  agent any
  stages {
    stage('Build') {
      steps {
        echo 'Build'
      }
    }
    stage('Test') {
      steps {
        echo 'Test'
      }
    }
    stage('Deploy') {
      steps {
        echo 'Deploy'
      }
    }
  }
}

Scripted Pipeline

Scripted pipelines use one or more node blocks to execute the core work. Stages are optional but can be added for better UI visibility.

node {
  stage('Build') {
    echo 'Build'
  }
  stage('Test') {
    echo 'Test'
  }
  stage('Deploy') {
    echo 'Deploy'
  }
}

Agent Configuration

The agent directive determines where the pipeline or a specific stage runs. Common forms are:

any : run on any available executor.

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

label : run on nodes matching a label, e.g., agent { label 'my-defined-label' }.

node : similar to label but allows additional settings such as customWorkspace.

dockerfile : build a container from a Dockerfile in the source repository.

docker : run steps inside an existing Docker image.

kubernetes : launch a pod in a Kubernetes cluster (requires the Kubernetes plugin).

Workspace Volumes (Kubernetes)

When using the Kubernetes agent, various workspace volume types can be configured: persistentVolumeClaimWorkspaceVolume: mount an existing PVC. nfsWorkspaceVolume: mount an NFS share. dynamicPVC: create a PVC dynamically and delete it after the build. emptyDirWorkspaceVolume: temporary directory that disappears with the pod. hostPathWorkspaceVolume: mount a directory from the node host (ensure proper permissions).

Post Actions

The post block runs after a pipeline or stage finishes. Supported conditions include always, changed, fixed, regression, failure, success, unstable, aborted, unsuccessful, and cleanup. Example:

post {
  always {
    echo 'I will always say Hello again!'
  }
}

Steps

Each stage contains a steps section where individual commands are executed, either directly with sh or via built‑in steps like echo.

stage('Example') {
  steps {
    echo 'Hello World'
    sh 'env && sleep 2'
  }
}

Directives

Directives provide additional configuration such as environment, options, parameters, triggers, input, and when. They can be defined at the pipeline level or within a stage.

Environment

Define global or stage‑specific environment variables. Credentials can be injected using the credentials() function, which creates variables for secret text, username/password, or secret files.

environment {
  NAME = 'zhangzhuo'
  KUBECONFIG = credentials('kubernetes-cluster')
}

Options

Common options include buildDiscarder, disableConcurrentBuilds, retry, timeout, and timestamps. Example at pipeline level:

options {
  timeout(time: 1, unit: 'HOURS')
  timestamps()
  buildDiscarder(logRotator(numToKeepStr: '3'))
  retry(3)
}

Parameters

Parameters allow users to supply values when triggering a build. Supported types are string, text, booleanParam, choice, and password. Example:

parameters {
  string(name: 'DEPLOY_ENV', defaultValue: 'staging')
  booleanParam(name: 'DEBUG_BUILD', defaultValue: true)
  choice(name: 'CHOICES', choices: ['one','two','three'])
}

Triggers

Automate pipeline execution with cron, upstream, or other triggers.

triggers {
  cron('H */4 * * 1-5') // every 4 hours on weekdays
  upstream(upstreamProjects: 'env', threshold: hudson.model.Result.SUCCESS)
}

Input

Interactive prompts can be added to request confirmation or additional parameters during a run.

input {
  message "Continue?"
  ok "Proceed"
  submitter "alice,bob"
  parameters {
    string(name: 'PERSON', defaultValue: 'Mr Jenkins')
  }
}

When

Conditional execution of stages based on branch, environment, expression, etc. Multiple conditions can be combined with allOf, anyOf, or not.

when {
  branch 'main'
  environment name: 'DEPLOY_TO', value: 'production'
}

Parallel

Run multiple branches concurrently within a stage.

stage('Parallel Stage') {
  parallel {
    stage('Branch A') { steps { echo 'On Branch A' } }
    stage('Branch B') { steps { echo 'On Branch B' } }
    stage('Branch C') {
      stages {
        stage('Nested 1') { steps { echo 'Nested 1' } }
        stage('Nested 2') { steps { echo 'Nested 2' } }
      }
    }
  }
}

Jenkinsfile Usage

Storing the Jenkinsfile in source control enables versioning, review, and collaboration. The article also lists useful built‑in environment variables such as BUILD_ID, BUILD_NUMBER, BUILD_TAG, JOB_NAME, NODE_NAME, JENKINS_URL, and WORKSPACE, and shows how to reference them in the pipeline.

pipeline {
  agent any
  stages {
    stage('Print env') {
      steps {
        echo "${env.BUILD_ID}"
        echo "${env.JENKINS_URL}"
      }
    }
  }
}

Dynamic Variables

Variables can be assigned from command output using returnStdout or capture exit status with returnStatus.

environment {
  CC = "${sh(returnStdout: true, script: 'echo -n clang')}"
  EXIT_STATUS = "${sh(returnStatus: true, script: 'exit 1')}"
}

Credentials Management

Credentials can be injected as secret text, username/password, or secret files. For username/password credentials, three variables are created: the combined USER:PASS string, *_USR, and *_PSW.

environment {
  BITBUCKET_COMMON_CREDS = credentials('harbor-account')
}
CI/CDDevOpsPipelineJenkinsDeclarativeScriptedJenkinsfile
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

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.