具有并行和不同容器的 Jenkins 管道

Jenkins pipelines with parallel and different containers

所以我已经运行基于来自以下示例的并行基础的 Jenkins 管道:Is it possible to create parallel Jenkins Declarative Pipeline stages in a loop?

我想运行每个作业在不同的隔离容器中,代理名称应该对所有这些都相同。尝试了几个选项,所有选项都以错误告终,我想我需要同时使用声明式和脚本式,但不确定如何使用。 我累的事情:

def generateTerraformStage(env) {
    return {
        agent { label 'local_terraform' }
        stage("stage: Terraform ${TERRAFORM_ACTION} ${env}") {
                echo "${env}"
                sleep 30
        }
    }
} 
stage('parallel stages') {
    agent { label 'local_terraform' }
    steps {
        script {
            parallel parallelStagesMapEnvironment
        }
    }
}

我在测试中遇到的错误之一:

"java.lang.NoSuchMethodError: No such DSL method 'agent' found among steps" and "java.lang.IllegalArgumentException: Expected named arguments but got org.jenkinsci.plugins.workflow.cps.CpsClosure2@560f3533"

只能使用脚本化管道创建动态并行阶段。 API 内置声明式管道不可用(如 agentoptionswhen 等)。

我没有看到任何你真正需要动态阶段的信息(例如基于第 3 方服务返回的值),所以我准备了两个解决方案:

  • 动态并行阶段 - 阶段是基于某些东西生成的
  • 静态并行阶段 - 你知道所有阶段(when 块可用于禁用这些不需要的阶段 - 例如传入参数)
pipeline {
  // ...
  stages {
    stage('dynamic parallel stages') {
      steps {
        script {
           // params.ENVS == ['envA', 'envB', 'envC']
           def values = params.ENVS.split(',')
           def stages = [:]
           for (def value in values) {
             stages[value] = generateTerraformStage(value)
           }
           parallel stages
        }
      }
    }
    stage('static parallel stages') {
      parallel {
        stage('envA') {
          agent { label 'local_terraform' }
          when {
            expression { return params.ENVS.split(',').contains('envA') }
          }
          steps {
            terraformStageLogic 'envA'
          }
        }
        stage('envB') {
          agent { label 'local_terraform' }
          when {
            expression { return params.ENVS.split(',').contains('envB') }
          }
          steps {
            terraformStageLogic 'envB'
          }
        }
        stage('envC') {
          agent { label 'local_terraform' }
          when {
            expression { return params.ENVS.split(',').contains('envC') }
          }
          steps {
            terraformStageLogic 'envC'
          }
        }
        // ...
      }
    }
  }
}

Closure<Void> generateTerraformStage(env) {
  return {
    node('local_terraform') {
      stage("stage: Terraform ${TERRAFORM_ACTION} ${env}") {
        echo "${env}"
        sleep 30
      }
    }
  }
}

void terraformStageLogic(env) {
  echo "${env}"
  sleep 30
}

当负责生成或执行其他阶段(dynamic parallel stagesstatic parallel stages)的阶段不使用工作区时,则不需要为其分配任何节点(浪费资源)。