在Declarative Pipeline模式的代码中,可能会在一个stages{…}中声明一窜嵌套的stages{…}, 并以顺序执行。需要指出的是,一个stage{…}必须有且只有一个steps{…}, 或者parallel{…} 或者stages{…}
看看下面这个顺序嵌套例子代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 1pipeline {
2 agent none
3 stages {
4 stage('Non-Sequential Stage') {
5 agent {
6 label 'for-non-sequential'
7 }
8 steps {
9 echo "On Non-Sequential Stage"
10 }
11 }
12 stage('Sequential') {
13 agent {
14 label 'for-sequential'
15 }
16 environment {
17 FOR_SEQUENTIAL = "some-value"
18 }
19 stages {
20 stage('In Sequential 1') {
21 steps {
22 echo "In Sequential 1"
23 }
24 }
25 stage('In Sequential 2') {
26 steps {
27 echo "In Sequential 2"
28 }
29 }
30 }
31 }
32 }
33}
34
35
这个例子展示了嵌套,其实更好的顺序执行stage的例子就是我们前面写过的 Build Test Deploy这三个stage.
认真看,可以看到这些特点。
- 所有的stage,都会内嵌在最外层的stages{…}
- 一个stage{…}下可以内嵌有且只有一个stages{…}
- 多层嵌套只支持在最后一个stage{…}里面
- 嵌套越多越复杂,最简单就是观察每一个stage的大括号的范围
原则上,我们尽量少写嵌套的stage{…},写了嵌套就意味很难维护。但是有时候,由于业务逻辑需要,和stage{…}组织结构好看,我们会写嵌套,嵌套里面可能存在顺序和平行的stage{…} 前面我们演示的demo都是顺序,也就是一个接着一个执行,下面我们来看看并行的stage{…}
并行stage{…}需要用到指令paraller, 有一个paraller{…} 里面包含多个stage{…},最后一个stage{…}内部支持嵌套多个stages{…}。在paraller{…}如果要设置只要里面有一个stage{…}运行失败就强制停止,可以使用表达式failFast true 来条件控制。
并行stage{…}举例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 1pipeline {
2 agent any
3 pipeline {
4 agent any
5 stages {
6 stage('Non-Parallel Stage') {
7 steps {
8 echo 'This stage will be executed first.'
9 }
10 }
11 stage('Parallel Stage') {
12 failFast true
13 parallel {
14 stage('并行一') {
15 steps {
16 echo "并行一"
17 }
18 }
19 stage('并行二') {
20 steps {
21 echo "并行二"
22 }
23 }
24 stage('并行三') {
25 stages {
26 stage('Nested 1') {
27 steps {
28 echo "In stage Nested 1 within Branch C"
29 }
30 }
31 stage('Nested 2') {
32 steps {
33 echo "In stage Nested 2 within Branch C"
34 }
35 }
36 }
37 }
38 }
39 }
40 }
41}
42
43
关于这个并行,我创建了一个jenkins job,跑一下就可以帮助你了解。
http://65.49.216.200:8080/job/paraller_demo/
运行完之后的stage 视图是这样的
并行1 并行2 并行3 三个stage之间的关系是并行的,上面截图显示都执行成功。这里我们测试一下如果并行二发生报错,会发生生成。在并行二里面的echo 改成echo1,再次运行。
由于我们添加了代码failFast true,但是并行二这个stage发生了报错。本来并行1 并行2 并行3下面两个嵌套的stage都在同一时间并发执行,但是这个job最终的结果是aborted, 从控制台日志或者UI显示灰色能看出来确实是中止了。
总结一下,paraller{…}这个要会使用,使用这个表示并行执行里面的多个stage。这里举例一下这个使用场景,例如我有一个模块的代码分别要在windows 和mac 和linux上三种环境下去测试。那么我可以提前准备好三个环境的agent node机器,然后一套环境写一个stage,把这三个stage都放在paraller{…}里面,让三个并行测试。paraller{…}上面一层这个stage名称就可以叫xxx模块兼容性测试。因为这三个环境都同等重要,你就可以设置failFast true,只要有一个不通过,就中止运行pipeline下面的代码。关于嵌套,非不得已,不要去使用,确实让其他人不好读代码和不好维护。
流程控制
由于pipeline是基于groovy语言开发的,所以支持在pipeline{…}代码块写流程控制语句代码和循环代码。原则上,大部分java和groovy的语法都可以在pipeline上得到很好的处理,但是还是有一些是不好兼容的,所以,Jenkins特意为了更好使用pipeline,开发了一些工具类,方便我们更好地在step中处理各种需求。接下来,我要带大家一起学习https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/
这个页面的一些常用的工具类的使用,算是一个实战练习过程吧。pipeline语法就学习完了,对了还有一种script pipeline我不打算介绍,从头到尾我们都在学习更容易维护和直观的Declarative Pipeline模式。下面写一个if控制语句来展开接下来我们要实战的练习。
项目job: http://65.49.216.200:8080/job/flow_control_demo/
jenkins pipeline代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 1pipeline {
2 agent any
3 stages {
4 stage('flow control') {
5 steps {
6 script {
7 if ( 10 == 10) {
8 println "pass"
9 }else {
10 println "failed"
11 }
12 }
13 }
14 }
15 }
16}
17
接下来,我会尽量把代码全部放github,真正模拟开发过程来介绍各种工具类的实战练习。