When working with Jenkins declarative pipelines, you'll often need to process lists of items like module names, server names, or configuration values. The Groovy-based syntax provides several ways to handle array iteration, each with its own advantages.
Here's the most straightforward way to iterate through your module list:
pipeline {
agent any
stages {
stage('Iterate Modules') {
steps {
script {
def allModules = ['module1', 'module2', 'module3', 'module4', 'module11']
for (module in allModules) {
echo "Processing module: ${module}"
}
}
}
}
}
}
You can also use these variations depending on your needs:
// Traditional for loop
for (int i = 0; i < allModules.size(); i++) {
echo "Module ${i+1}: ${allModules[i]}"
}
// Each closure syntax
allModules.each { module ->
echo "Current module: $module"
}
// EachWithIndex for position tracking
allModules.eachWithIndex { module, index ->
echo "Module #${index + 1}: $module"
}
For more advanced scenarios where you need parallel execution:
pipeline {
agent any
stages {
stage('Parallel Module Processing') {
steps {
script {
def allModules = ['module1', 'module2', 'module3', 'module4', 'module11']
def parallelStages = [:]
allModules.each { module ->
parallelStages["Process ${module}"] = {
stage("Process ${module}") {
echo "Building ${module}"
// Add your build steps here
}
}
}
parallel parallelStages
}
}
}
}
}
Always include proper error handling:
script {
try {
allModules.each { module ->
try {
// Your module processing code
} catch (ex) {
echo "Error processing ${module}: ${ex.getMessage()}"
// Continue with next module
}
}
} catch (e) {
currentBuild.result = 'FAILURE'
error "Pipeline failed: ${e.getMessage()}"
}
}
When dealing with large arrays:
- Consider chunking very large lists to avoid memory issues
- For long-running operations, use timeouts
- Monitor your Jenkins master's resource usage
pipeline {
agent any
environment {
allModules = ['module1', 'module2', 'module3', 'module4', 'module11']
}
stages {
stage('Loop Example') {
steps {
script {
// Method 1: Classic for loop
for (int i = 0; i < allModules.size(); i++) {
echo "Processing module: ${allModules[i]}"
}
// Method 2: Enhanced for loop (recommended)
for (module in allModules) {
echo "Current module: ${module}"
}
// Method 3: Using each() closure
allModules.each { module ->
echo "Module via closure: ${module}"
}
// Method 4: Parallel execution (for independent tasks)
def parallelSteps = [:]
allModules.each { module ->
parallelSteps["Process ${module}"] = {
echo "Parallel processing: ${module}"
}
}
parallel parallelSteps
}
}
}
}
}
When working with loops in Jenkins declarative pipelines:
- Always use
script
blocks for imperative logic - For simple iteration, the enhanced for loop is most readable
- Consider parallel execution when modules can be processed independently
- Remember that pipeline steps (like
sh
orbat
) need to be inside the loop body
pipeline {
agent any
stages {
stage('Dynamic Stages') {
steps {
script {
def modules = ['module1', 'module2', 'module3']
modules.each { module ->
stage("Process ${module}") {
echo "Building ${module}"
// Add your build steps here
}
}
}
}
}
}
}
To make your loops more robust:
allModules.each { module ->
try {
echo "Processing ${module}"
// Your logic here
} catch (Exception e) {
echo "Failed processing ${module}: ${e.getMessage()}"
// Continue with next module
}
}
For large lists, consider these approaches:
- Use
parallel
steps when possible - Limit the number of concurrent executions with
parallel
branches - Consider splitting very large lists into batches