将轻量级执行程序用于声明性管道阶段(代理无)

run*_*ike 19 jenkins jenkins-pipeline

我正在使用具有声明性语法的Jenkins Pipeline,目前具有以下阶段:

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

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

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

  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 {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里遗漏了什么,或者在当前版本中是不可能的?

Chr*_*Orr 15

设置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()}"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

您必须stash在构建步骤之后使用.正如您所注意到的,目前无法正常parallel进行此操作,因此您必须另外使用一个script块,以便在并行步骤之后/之前为存储/取消存储写入一段Scripted Pipeline.