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


8 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