所以我花了一整天时间试图弄清楚如何使用多个Docker图像配置一个简单的Jenkins管道,我一点都不高兴。
我需要在几个不同的docker容器上执行几个阶段(准备,构建,测试,文档)(目前我只选择了三个标准的Python容器)。如果那些并行运行会很好,但我只找到了这个解决方案,它将所有阶段合并为一个(因此在Blue Ocean UI中创建了一个不那么丰富的概述):Jenkins Pipeline Across Multiple Docker Images
所以我最终得到了下面的配置,这很丑陋(到处都是代码重复),但或多或少在经典UI中创建了一个好看的概述:
Blue Ocean UI中的信息量不足
来自junit
的可接受的测试概述,它结合了每个阶段的所有测试但如果任何测试失败,则相应的"版本"显示:
然而,最令人烦恼的是,你无法看到哪一步失败了。如果Python 2.7失败,其他所有内容也会被标记为失败,您甚至不会看到哪个阶段失败。
我尝试了很多不同的方法,我想知道应该怎么做。这应该和Jenkins一样常见,所以我想我对此有一些普遍的误解(对我来说绝对是新的)管道/节点/标签/阶段/步骤/声明/脚本/ groovy / blueocean东西... < / p>
应该可以为它们中的每一个定义一些docker容器列表(可能是可自定义的阶段/步骤)并且并行运行它们并且在Blue Ocean和Classic UI中很好地显示它,不应该是它?
node {
stage("Python 2.7.14") {
checkout scm
docker.image('python:2.7.14').inside { // just a dummy for now
stage("Prepare") { sh 'python --version' }
stage("Build") { sh 'ls -al' }
}
}
stage("Python 3.5.4") {
checkout scm
docker.image('python:3.5.4').inside {
stage("Prepare") { sh 'python -m venv venv' }
stage("Build") {
sh """
. venv/bin/activate
make install-dev
"""
}
stage('Test') {
sh """
. venv/bin/activate
make test
"""
}
stage('Docs') {
sh """
. venv/bin/activate
make doc-dependencies
cd docs
make html
"""
}
}
}
stage("Python 3.6.4") {
checkout scm
docker.image('python:3.5.4').inside {
stage("Prepare") { sh 'python -m venv venv' }
stage("Build") {
sh """
. venv/bin/activate
make install-dev
"""
}
stage('Test') {
sh """
. venv/bin/activate
make test
"""
}
stage('Docs') {
sh """
. venv/bin/activate
make doc-dependencies
cd docs
make html
"""
}
}
}
}
更新:这是在步骤失败时在Blue Ocean UI中的样子,在这种情况下&#34;测试&#34; Python 3.5.4和3.6.4都失败了,但看起来一切都失败了。
Python 2.7.14和3.5.4阶段也已折叠,无法单独查看。如果我点击其中一个,所有步骤都显示为绿色,尽管在这种情况下. venv/bin/activate make test
失败:
答案 0 :(得分:6)
所以这就是我最终的结果。肯定有更好的解决方案,但我必须继续前进。我希望及时收集一些(更好的)答案,我不会将其标记为“解决方案”;)
首先,斯蒂芬·金斯幻灯片的一些学分(标题上写着“声明”,但有关于脚本化管道的一些很好的例子):(Declarative) Jenkins Pipelines
以下是我的gist on GitHub,其中包含以下代码段:
def docker_images = ["python:2.7.14", "python:3.5.4", "python:3.6.2"]
def get_stages(docker_image) {
stages = {
docker.image(docker_image).inside {
stage("${docker_image}") {
echo 'Running in ${docker_image}'
}
stage("Stage A") {
switch (docker_image) {
case "python:2.7.14":
sh 'exit 123' // for python 2.7.14 we force an error for fun
break
default:
sh 'sleep 10' // for any other docker image, we sleep 10s
}
sh 'echo this is stage A' // this is executed for all
}
stage("Stage B") {
sh 'sleep 5'
sh 'echo this is stage B'
}
stage("Stage C") {
sh 'sleep 8'
sh 'echo this is stage C'
}
}
}
return stages
}
node('master') {
def stages = [:]
for (int i = 0; i < docker_images.size(); i++) {
def docker_image = docker_images[i]
stages[docker_image] = get_stages(docker_image)
}
parallel stages
}
我试图让它易于使用:
stages
函数中定义get_stages()
python:2.7.14
),则可以使用简单的switch
。这也可以通过特殊情况的双重映射('images' - &gt;'stage'='steps')和默认的后备双映射来实现,但我会将其留作读者练习。 (老实说,我无法弄清楚正确的,支持的Groovy-lang语法)这就是经典和蓝海UI中的一切都很好的样子(众所周知,Blue Ocean UI无法在并行运行中显示多个阶段,请参阅JENKINS-38442):
如果Stage A
中的python:2.7.14
失败,这就是输出: