Operations 24 min read

Understanding Jenkins Pipelines: Declarative vs Scripted Syntax, Agents, Stages, Post Actions and Advanced Features

This article provides a comprehensive guide to Jenkins pipelines, explaining the difference between declarative and scripted syntax, detailing pipeline components such as agents, stages, steps, post actions, directives, triggers, environment variables, credential handling, and Kubernetes integration for modern CI/CD workflows.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Understanding Jenkins Pipelines: Declarative vs Scripted Syntax, Agents, Stages, Post Actions and Advanced Features

What Is a Pipeline

Jenkins supports two types of pipelines: Declarative Pipeline and Scripted Pipeline . The scripted form is used in older Jenkins versions, while the newer versions recommend the declarative syntax.

Declarative Pipeline

In a declarative pipeline the entire process is defined inside a pipeline {} block. Key directives include agent , stage , and steps .

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

Parameters

agent any : run on any available executor or a specific node.

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

steps : the actual commands executed within a stage.

Scripted Pipeline

The scripted syntax uses one or more node blocks to perform the core work.

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

Agents

Agents specify where the pipeline or a particular stage runs. They can be defined at the top level or per stage.

Common Agent Types

any : any available agent.

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

label 'my-defined-label' : run on a node with a specific label.

node { label 'role-master' } : similar to label but allows extra options such as customWorkspace .

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

docker { image 'my-image' } : run stages inside an existing Docker image.

kubernetes { ... } : use the Kubernetes plugin to launch dynamic agents.

agent {
  kubernetes {
    cloud 'kubernetes'
    slaveConnectTimeout 1200
    workspaceVolume emptyDirWorkspaceVolume()
    yaml '''
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
  - args: ['$(JENKINS_SECRET)', '$(JENKINS_NAME)']
    image: '192.168.10.15/kubernetes/jnlp:alpine'
    name: jnlp
    imagePullPolicy: IfNotPresent
  - command:
      - "cat"
    image: "192.168.10.15/kubernetes/alpine:latest"
    name: "date"
    tty: true
  restartPolicy: Never
''' 
  }
}

Post Actions

Post sections run after a pipeline or stage finishes and can react to different outcomes such as always , failure , success , etc.

// Jenkinsfile (Declarative Pipeline)
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!' }
  }
}

Directives

Directives provide additional configuration such as environment variables, options, parameters, triggers, input prompts, conditional execution ( when ), and parallel stages.

Environment

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

timeout(time: 1, unit: 'HOURS')

timestamps()

buildDiscarder(logRotator(numToKeepStr: '3'))

quietPeriod(10)

retry(3)

Parameters

Define user‑supplied values that appear when the build is triggered.

pipeline {
  agent any
  parameters {
    string(name: 'DEPLOY_ENV', defaultValue: 'staging')
    booleanParam(name: 'DEBUG_BUILD', defaultValue: true)
    choice(name: 'CHOICES', choices: ['one','two','three'])
    password(name: 'PASSWORD', defaultValue: 'SECRET')
  }
  stages { /* ... */ }
}

Triggers

Automate pipeline starts using cron , upstream , or other mechanisms.

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

Input

Interactive prompts can request confirmation or additional parameters.

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

When

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

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

Parallel

Run multiple branches concurrently.

pipeline {
  agent any
  stages {
    stage('Parallel Stage') {
      parallel {
        stage('A') { steps { echo 'A' } }
        stage('B') { steps { echo 'B' } }
        stage('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.

Built‑in Environment Variables

Common variables include BUILD_ID , BUILD_NUMBER , BUILD_TAG , BUILD_URL , JOB_NAME , NODE_NAME , JENKINS_URL , and WORKSPACE . They can be accessed via env.VAR_NAME .

Dynamic Variables

Use sh(returnStdout: true, script: '...') or sh(returnStatus: true, script: '...') to capture command output or exit status.

Credentials

The credentials() function injects secret text, username/password, or secret files into the environment, automatically creating auxiliary variables for username and password.

// Secret text
environment { AWS_ACCESS_KEY_ID = credentials('txt1') }
// Username/password
environment { BITBUCKET_COMMON_CREDS = credentials('harbor-account') }
// Secret file (e.g., kubeconfig)
environment { MY_KUBECONFIG = credentials('kubernetes-cluster') }

These features together allow you to build robust, reproducible CI/CD pipelines that run on bare agents, Docker containers, or Kubernetes pods.

CI/CDKubernetesdevopsJenkinsDeclarative PipelineScripted Pipeline
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login 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.