在Jenkins声明性流水线中在同一代理上运行并行阶段

45次阅读
没有评论

问题描述

正在使用Jenkins流水线,并在测试阶段中使用并行步骤,如下所示:

pipeline {
    agent { label 'php' }
    stages {
        stage('build') {
            steps {
                // 构建步骤内容
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    steps {
                        // 单元测试步骤内容
                    }
                }
                stage('integration tests') {
                    steps {
                        // 集成测试步骤内容
                    }
                }
            }
        }
        stage('deploy') {
            steps {
                // 部署步骤内容
            }
        }
    }
}

目前,流水线在单一代理上运行正常。但现在,用户希望添加一个需要手动输入的步骤,并且这个步骤不应该保持代理运行。代理是云服务器,根据需求启动和停止。

为了实现这一点,用户将流水线分配给了”none”代理,并且在除了请求输入的步骤外的所有步骤中指定了实际的代理,如下所示:

pipeline {
    agent none
    stages {
        stage('build') {
            agent { label 'php' }
            steps {
                // 构建步骤内容
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    agent { label 'php' }
                    steps {
                        // 单元测试步骤内容
                    }
                }
                stage('integration tests') {
                    agent { label 'php' }
                    steps {
                        // 集成测试步骤内容
                    }
                }
            }
        }
        stage('deploy staging') {
            agent { label 'php' }
            steps {
                // 部署到暂存环境的步骤内容
            }
        }
        stage('confirm release') {
            steps {
                input { message '发布?' }
            }
        }
        stage('deploy production') {
            agent { label 'php' }
            steps {
                // 部署到生产环境的步骤内容
            }
        }
    }
}

已经使用stashunstash将后续阶段需要的文件进行传递。这个方法有效,但存在两个问题:
1. 在每个单独的阶段之间执行stashunstash会造成开销。用户更希望在手动输入之前的所有阶段在单个工作空间中执行。但是,agent只允许在包含步骤的阶段中使用。
2. 每个并行阶段占用一个代理。如果只有一个空闲代理,就不会进行并行执行,与之前不同。

用户可以接受(1)的情况,如果没有其他方式的话。但对于我来说,一个代理上的并行执行非常重要。在当前的设置中,是否有可能实现这一点?如果不行,有哪些类似的选项可以达到类似的效果?

解决方案

方案

为了在Jenkins声明性流水线中在同一代理上执行并行阶段,可以按照以下步骤操作。

  1. 首先,可以使用嵌套的script块来实现在并行阶段中的不同代理。
  2. 使用node来指定一个代理,然后在script块中定义要在该代理上运行的步骤。

下面是调整后的流水线示例代码:

pipeline {
    agent none
    stages {
        stage('build') {
            agent { label 'php' }
            steps {
                echo "构建"
                sh "ls -lrt && touch build.txt"
            }
        }
        stage('test') {
            parallel {
                stage('unit tests') {
                    steps {
                        script {
                            node('php') {
                                echo "单元测试"
                                sh "ls -lrt && touch ut.txt"
                                sleep(time:10,unit:'SECONDS')
                            }
                        }
                    }
                }
                stage('integration tests') {
                    steps {
                        script {
                            node('php') {
                                echo "集成测试"
                                sh "ls -lrt && touch it.txt"
                                sleep(time:10,unit:'SECONDS')
                            }
                        }
                    }
                }
            }
        }
        stage('deploy staging') {
            agent { label 'php' }
            steps {
                echo "部署到暂存环境"
                sh "ls -lrt && touch dep.txt"
            }
        }
        stage('confirm release') {
            steps {
                input message: '发布?'
            }
        }
        stage('deploy production') {
            agent { label 'php' }
            steps {
                echo "部署到生产环境"
                sh "ls -lrt && touch produ.txt"
            }
        }
    }
}

在上述示例中,我们使用了script块,并在其中使用node('php')来指定了特定的代理。这样,我们可以在并行阶段中使用不同的代理,并在各个代理上运行所需的步骤。

请注意,这个示例是经过测试的,并且在日志中也可以确认可以选择不同的代理。值得注意的是,这是一个声明性流水线。

正文完