一尘不染

使用轻量级执行程序进行声明式管道阶段(代理无)

jenkins

我正在将Jenkins Pipeline与声明性语法一起使用,目前处于以下阶段:

  1. 准备
  2. 构建(两组并行的步骤)
  3. 测试(也是两组平行的步骤)
  4. 询问是否/在哪里部署
  5. 部署

对于步骤1、2、3和5,我需要和代理(执行者),因为它们在工作区上进行实际工作。对于步骤4,我不需要一个,并且我不想在等待用户输入时阻止我可用的执行程序。对于经典的脚本化语法,这似乎被称为“轻量级”执行器或“轻量级”执行器,但是我找不到有关如何使用声明性语法实现此信息的任何信息。

到目前为止,我已经尝试过:

  1. 直接在管道选项中设置代理,然后agent none在舞台上进行设置。这没有任何效果,并且管道正常运行,在等待输入时阻塞了执行程序。在文档中也提到它不会起作用,但是我想还是应该尝试一下。
  2. 设置agent none管道选项,然后为每个阶段(#4除外)设置一个代理。不幸的是,但是可以预料的是,这会为每个阶段分配一个新的工作区,这反过来又需要我存储和取消存储。这既麻烦又使我在并行阶段(2和3)中遇到了其他问题,因为我不能在parallel构造之外使用代码。我假设并行步骤在同一个工作空间中运行,所以在这两个环境中存储/取消存储将产生不幸的结果。

这是我的Jenkinsfile的概述:

pipeline {
    agent {
        label 'build-slave'
    }
    stages {
        stage("Prepare build") {
            steps {
                // ...
            }
        }
        stage("Build") {
            steps {
                parallel(
                    frontend: {
                        // ...
                    },
                    backend: {
                        // ...
                    }
                )
            }
        }
        stage("Test") {
            steps {
                parallel(
                    jslint: {
                        // ...
                    },
                    phpcs: {
                        // ...
                    },
                )
            }
            post {
                // ...
            }
        }
        stage("Select deploy target") {
            steps {
                script {
                    // ... code that determines choiceParameterDefinition based on branch name ...
                    try {
                        timeout(time: 5, unit: 'MINUTES') {
                            deployEnvironment = input message: 'Deploy target', parameters: [choiceParameterDefinition]
                        }
                    } catch(ex) {
                        deployEnvironment = null
                    }
                }
            }
        }
        stage("Deploy") {
            when {
                expression {
                    return binding.variables.get("deployEnvironment")
                }
            }
            steps {
                // ...
            }
        }
    }
    post {
        // ...
    }
}

我在这里缺少什么吗,还是在当前版本中不可能?


阅读 258

收藏
2020-07-25

共1个答案

一尘不染

设置agent none在最高级别,然后agent { label 'foo' }在每个阶段设置,再设置在舞台agent none上,这input似乎对我来说是预期的。

即,执行某些工作的每个阶段都在同一个代理上运行,而该input阶段不消耗任何代理上的执行程序。

pipeline {
    agent none
    stages {
        stage("Prepare build") {
            agent { label 'some-agent' }
            steps {
                echo "prepare: ${pwd()}"
            }
        }
        stage("Build") {
            agent { label 'some-agent' }
            steps {
                parallel(
                    frontend: {
                        echo "frontend: ${pwd()}"
                    },
                    backend: {
                        echo "backend: ${pwd()}"
                    }
                )
            }
        }
        stage("Test") {
            agent { label 'some-agent' }
            steps {
                parallel(
                    jslint: {
                        echo "jslint: ${pwd()}"
                    },
                    phpcs: {
                        echo "phpcs: ${pwd()}"
                    },
                )
            }
        }
        stage("Select deploy target") {
            agent none
            steps {
                input message: 'Deploy?'
            }
        }
        stage("Deploy") {
            agent { label 'some-agent' }
            steps {
                echo "deploy: ${pwd()}"
            }
        }
    }
}

但是,不能保证在管道中使用相同的代理标签将总是最终使用相同的工作空间,例如,当第一个构建正在等待时,作为同一作业的另一个构建input

您将必须stash在构建步骤之后使用。如您所述,目前无法正常完成此操作parallel,因此您必须另外使用一个script块,以便在并行步骤之后/之前编写脚本管道的代码段以进行隐藏/取消隐藏。

2020-07-25