Creating Scripted Pipelines
1. Understanding Groovy Syntax
Jenkins Pipeline scripts are written in Groovy, a dynamic language that runs on the Java Virtual Machine (JVM). Understanding basic Groovy syntax is essential for writing effective Jenkins pipelines.
| Concept | Description | Example |
|---|---|---|
| Variables | Declared with def keyword or inferred type |
|
| Functions | Defined using def keyword followed by function name and parameters |
|
| Control Structures | Supports standard control flow like if/else, for, while |
|
| Lists and Maps | Lists use square brackets, maps use curly braces | |
Example: Basic Pipeline Script
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
}
2. Using Node and Stage Blocks
| Property | Description | Example |
|---|---|---|
| node | Allocates a node to run the pipeline or stage on. | node('label') { ... } |
| stage | Defines a stage in the pipeline with a name and steps. | stage('Build') { steps { ... } } |
Example: Basic Node and Stage Usage
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
}
Example: Node with Label
pipeline {
agent {
node {
label 'ubuntu-latest'
}
}
stages {
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
node block is used to allocate an executor for the pipeline or stage, and stage blocks define distinct phases of a Jenkins pipeline.
3. Defining Variables and Functions
| Variable Type | Declaration | Description | Usage Example |
|---|---|---|---|
| Environment Variables | env.VAR_NAME |
Accessible in pipeline steps, set via Jenkins UI or CLI | sh "echo ${env.VAR_NAME}" |
| Pipeline Variables | params.VAR_NAME |
Defined in pipeline script or via UI, used for configuration | echo "Build number: ${params.BUILD_NUMBER}" |
| Global Variables | global.VAR_NAME |
Defined at the top level of pipeline script | |
Example: Setting and Using Pipeline Variables
pipeline {
agent any
parameters {
string(name: 'BUILD_NUMBER', defaultValue: '1', description: 'Build number')
}
stages {
stage('Example') {
steps {
script {
def buildNumber = params.BUILD_NUMBER
echo "Current build number: ${buildNumber}"
}
}
}
}
}
Example: Using Environment Variables
pipeline {
agent any
environment {
NODE_ENV = 'production'
API_URL = 'https://api.example.com'
}
stages {
stage('Print Environment') {
steps {
sh "echo NODE_ENV is ${env.NODE_ENV}"
sh "echo API_URL is ${env.API_URL}"
}
}
}
}
Example: Defining Functions in Jenkins Pipeline
def deployToStaging() {
sh "echo Deploying to staging environment"
}
pipeline {
agent any
stages {
stage('Deploy') {
steps {
script {
deployToStaging()
}
}
}
}
}
script block can be reused throughout the pipeline.
4. Using Try-Catch-Finally Blocks
Try-catch-finally blocks in Jenkins scripted pipelines provide structured error handling and resource management. They allow you to handle exceptions gracefully, execute cleanup code, and ensure that critical operations are completed even when errors occur.
| Block | Description | Usage |
|---|---|---|
| try | Contains code that might throw an exception. | try { // code } catch (e) { ... } |
| catch | Handles exceptions thrown in the try block. | catch (Exception e) { // handle error } |
| finally | Executes code regardless of whether an exception occurred. | finally { // cleanup code } |
Example: Basic Try-Catch-Finally Usage
pipeline {
agent any
stages {
stage('Example') {
steps {
script {
try {
sh 'echo "Starting operation..."'
sh 'exit 1' // Simulate failure
} catch (e) {
echo "Caught exception: ${e}"
} finally {
echo "Cleanup operations..."
}
}
}
}
}
}
Example: Handling Specific Exceptions
pipeline {
agent any
stages {
stage('Example') {
steps {
script {
try {
sh 'ls /nonexistent'
} catch (FileNotFoundException e) {
echo "File not found: ${e}"
} catch (Exception e) {
echo "General error occurred: ${e}"
} finally {
echo "Always executed"
}
}
}
}
}
}
finally block is always executed, even if there's a return statement in the try or catch block.
Key Points
- The
tryblock contains code that might throw an exception. - The
catchblock handles specific or general exceptions. - The
finallyblock runs regardless of exception occurrence. - Use specific exception types for better error handling.
5. Implementing Conditional Logic
| Condition Type | Description | Usage Example |
|---|---|---|
| when | Defines when a stage should run based on various conditions like branch, environment, or changes in SCM | |
| when changeset | Triggers the stage only if there are changes in the SCM | |
| when environment | Runs the stage only if an environment variable matches a specific value | |
Example: Using when with multiple conditions
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
stage('Deploy') {
when {
allOf {
branch 'main'
environment name: 'ENV', value: 'production'
}
}
steps {
echo 'Deploying to production'
}
}
}
}
when directive can be used at the stage or parallel stage level.
6. Using Loops
| Loop Type | Description | Example |
|---|---|---|
| for | Iterates over a list or range | |
| while | Continues while a condition is true | |
| until | Continues until a condition becomes true | |
Example: For Loop with List
def fruits = ['apple', 'banana', 'orange']
for (fruit in fruits) {
echo "Fruit: ${fruit}"
}
Example: While Loop with Conditional Check
int i = 0
while (i < 3) {
echo "Processing item: ${i}"
i++
}
7. Calling External Scripts
| Script Type | Invocation Method | Notes |
|---|---|---|
| Shell Script | sh 'script.sh' |
Executes shell script in Jenkins workspace |
| Python Script | sh 'python3 script.py' |
Requires Python installed on Jenkins node |
| Groovy Script | sh 'groovy script.groovy' |
Can be executed within Jenkins pipeline |
Example: Calling External Shell Script
pipeline {
agent any
stages {
stage('Run External Script') {
steps {
sh 'chmod +x ./deploy.sh'
sh './deploy.sh'
}
}
}
}
Example: Passing Parameters to Script
pipeline {
agent any
stages {
stage('Execute With Args') {
steps {
sh "bash ./script.sh --env production --version v1.2.3"
}
}
}
}
8. Using Shared Libraries
Shared Libraries in Jenkins allow you to reuse code across multiple pipelines. They are stored as Git repositories and can contain functions, variables, and other reusable components.
| Property | Description | Example |
|---|---|---|
| library.name | Name of the library to be used in the pipeline | mySharedLib |
| library.version | Version of the library to use (e.g., branch, tag, or commit) | master |
| library.defaultVersion | Default version to use if not specified in the pipeline | v1.0 |
Example: Using a Shared Library in a Pipeline
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
// Load the shared library
def myLib = library('mySharedLib@master')
// Use a function from the library
myLib.myFunction()
}
}
}
}
}
Manage Jenkins > Configure System > Global Tool Configuration.
Key Points
- Shared libraries promote code reuse across pipelines.
- They are managed via Git repositories and can be versioned.
- Libraries can contain Groovy classes, functions, and global variables.
9. Handling Exceptions
| Exception Type | Description | Handling Strategy |
|---|---|---|
| IOException | Thrown when I/O operations fail, such as file read/write errors. | Use try-catch blocks to handle and log the error appropriately. |
| AbortException | Indicates that a build was aborted by the user or system. | Implement catch (AbortException e) to gracefully handle build interruptions. |
| GroovyRuntimeException | Occurs during Groovy script execution errors. | Wrap in try-catch and provide meaningful error messages to the user. |
Example: Catching and Logging Exceptions
try {
sh "ls -l /nonexistent"
} catch (IOException e) {
echo "Caught IOException: " + e.getMessage()
currentBuild.result = "FAILURE"
}
Example: Handling Build Aborts
try {
// Some long-running operation
sh "sleep 30"
} catch (AbortException e) {
echo "Build was aborted: " + e.getMessage()
// Optionally mark build as unstable or failed
currentBuild.result = "UNSTABLE"
}
10. Using Parallel Execution
Parallel execution in Jenkins allows you to run multiple stages concurrently, which can significantly reduce build times for independent tasks.
| Property | Description | Example |
|---|---|---|
| parallel | Defines a set of stages to run in parallel | |
Example: Parallel Pipeline Stages
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
echo 'Running unit tests'
}
}
stage('Integration Tests') {
steps {
echo 'Running integration tests'
}
}
}
}
stage('Deploy') {
steps {
echo 'Deploying...'
}
}
}
}