How to Iterate Through Arrays in Jenkins Declarative Pipeline Using For Loops


32 views

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 or bat) 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