具有并行和不同容器的 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 内置声明式管道不可用(如 agent
、options
、when
等)。
我没有看到任何你真正需要动态阶段的信息(例如基于第 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 stages
和static parallel stages
)的阶段不使用工作区时,则不需要为其分配任何节点(浪费资源)。
所以我已经运行基于来自以下示例的并行基础的 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 内置声明式管道不可用(如 agent
、options
、when
等)。
我没有看到任何你真正需要动态阶段的信息(例如基于第 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 stages
和static parallel stages
)的阶段不使用工作区时,则不需要为其分配任何节点(浪费资源)。