Jenkins流水线pipelinle用法
官网地址:
https://www.jenkins.io/zh/doc/book/pipeline/syntax/
Pipeline支持两种语法: Declarative Pipeline(声明式pipeline,在pipeline2.5中引入,结构化方式)和Scripted Pipeline(脚本式pipeline),两者都支持建立连续输送的Pipeline,建议使用声明式Pipeline的方式进行编写,声明式pipeline必须包含在固定格式的pipeline{}内,注意在pipeline{}中所有模块的大括号都要是英文状态下的,否则报错
声明式pipeline一般定义在jenkinsfile中(此名字可自定义的,但是要与Jenkins中配置的一致),然后将jenkinsfile放在gitlab中,可与代码放在一起或者单独放一个同一个仓库下的不同分支中(建议放在不同分支下,拉取推送代码对它没影响)
流水线的大致工作流程为:
- jenkins连接gitlab来获取代码与jenkinsfile文件
- jenkins根据定义的Jenkinsfile文件来执行Jenkinsfile中的pipeline流水线
本例子演示的是将Jenkinsfile与源代码分开存放,Jenkinsfile放在dev分支下,源代码放在main分支下
演示
1、首先在dev分支下新建文件,如图:

2、输入文件名以及文件内容,点击下方的Commit changes,如图:

- 第4行的括号里只是说明作用,内容可自定义
3、打开Jenkins,创建流水线项目,如图:

在定义位置选择声明式流水线,然后配置git地址和凭据,如图:

选择Jenkinsfile所在的分支,Jenkinsfile名称要与gitlab中定义的要一致,如图:

注:此处的主要目的是从dev分支来拉取Jenkinsfile文件,然后根据Jenkinsfile内容才开始正式的构建过程
4、构建Jenkins,可以看到构建成功,一个简单的流水线完成了,如图:

agent模块
agent指定了pipeline脚本在哪台机器或者容器或者pod中运行,因为jenkins的工作模式有master-slave模式,因此pipeline可以放到其他slave中执行,如果agent后面写着any,则表示可以在任意节点执行,如果master或者slave配置了标签,那么pipeline可以在执行标签的节点上运行,语法如下:
pipeline {
agent {
node {label: 'hello'}
}
}
agent也可以写到stage里,表示特定的stage模块在指定的标签节点运行,如下:
pipeline {
agent any
stages {
stage('hello') {
agent {
node {label: 'hello'}
}
}
}
}
注:agent模块不可省略
stages、stage、steps模块
stages模块由多个stage组成,一个stage表示一个阶段,一个阶段又由多个步骤组成,每个步骤使用steps表示,steps中只要用于执行具体的命令,例如,执行echo命令,如下:
pipeline {
agent any
stages {
stage("echo") {
steps {
echo "100000"
}
}
}
}
注:stage后面的括号内容是注释作用,可自定义的
steps模块下可定义script部分,然后在里面可执行各种shell命令或者脚本,如图:

sh 后面使用”’ ”’或者””” “””都可以,但是三引号里面就不用使用//来注释了,否则报错
post模块
在stages或者单个stage模块后定义post模块,用来表示整个stages或者单个stage完成后需要执行的动作,比如配置钉钉告警或者微信告警
修改上述Jenkins文件,添加post模块,上图在stage和stages后都添加了,如图:

从打印结果来看,在steps和stages执行后都调用了post,如图:

post可以定义多个条件块,条件里写要执行的步骤,条件块如下:
- always:无论当前执行结果是什么状态都执行
- changed:当前完成状态和上一步完成状态不同则执行
- fixed:上一步状态失败或者不稳定(unstable),当前状态为成功时
- regression:上一次成功,当前失败,不稳定或者中止(aborted)时执行
- aborted:当前执行结果是中止状态时执行(一般人为中止)
- failure:当前状态为失败时执行
- success:当前状态为成功时执行
- unstable :当前状态为不稳定时执行
- cleanup:清理条件块,不论当前状态是什么,其他条件块执行完成后都执行
post中定义多个条件块语法如下:
post {
success {
echo "hello"
}
failure {
echo "world"
}
.............
}
environment模块
environment模块用于设置环境变量,可定义在pipeline或stage部分
继续修改Jenkinsfile文件,添加环境变量,如图:

Jenkins执行结果如下,环境变量已经打印出来,如图:

tools模块
tools会自动下载并安装我们指定的工具,并将其加入PATH变量中,可定义在pipeline或stage中
例如如果构建java应用需要maven,但是机器没有安装,此时就可以执行,如下:
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1'
}
}
input模块
定义在stage部分,会暂停pipeline,提示你输入内容
options模块
用于配置Jenkins pipeline本身的选项,options指令可定义在stage或pipeline部分,如下:
options {
retry(3) //执行失败时尝试3次
timeout(time: 1, unit: 'HOURS') //超时1小时停止,MINUTES表示分
}
更多用法查看官方文档
parallel
并行执行多个step。在pipeline插件1.2版本后,parallel开始支持对多个阶段(stage)进行并行执行,注意,一个阶段必须只有一个 steps 或 parallel 的阶段,嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。任何包含 parallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps
下面是一段简单的并行执行的代码,如图:

注:通过添加 failFast true 到包含 parallel`的 `stage 中, 当其中一个进程失败时,你可以强制所有的 parallel 阶段都被终止
triggers模块
triggers 指令定义了流水线被重新触发的自动化方法,可用触发器为cron,pollSCM,upstream
- cron:接收 cron 样式的字符串来定义要重新触发流水线的常规间隔 ,比如:
triggers { cron('H */4 * * 1-5') } - pollSCM:接收 cron 样式的字符串来定义一个固定的间隔,在这个间隔中,Jenkins 会检查新的源代码更新。如果存在更改, 流水线就会被重新触发。例如:
triggers { pollSCM('H */4 * * 1-5') } - upstream:接受逗号分隔的工作字符串和阈值。 当字符串中的任何作业以最小阈值结束时,流水线被重新触发。例如:
triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }
pipeline {
agent any
triggers {
cron('H */4 * * 1-5')
}
}
when模块
when 指令允许流水线根据给定的条件决定是否应该执行阶段。 when 指令必须包含至少一个条件,如果 when 指令包含多个条件, 所有的子条件必须返回True,阶段才能执行。 这与子条件在 allOf 条件下嵌套的情况相同
内置条件有:branch、environment、not、allOf、anyOf
branch:当正在构建的分支与模式给定的分支匹配时,执行这个阶段, 例如: when { branch 'master' }。注意,只有多分支流水线的时候才会生效,配置方法如下:

environment:当指定的环境变量是给定的值时,执行这个步骤
下面例子定义了两个环境变量height和age,然后在when中进行判断,如图:

- name:对应的就是环境变量中的变量名,固定格式
- value:对应的就是环境变量中的变量值,固定格式
查看Jenkins执行结果,如图:

从上图看出,dev分支部分条件不符合,因此不执行,main分支符合,所以执行
expression:当指定的Groovy表达式评估为true时,执行这个阶段
下面例子修改jenkinsfile,添加表达式,如图:

执行Jenkins,结果如下:

从上图看出,因为第一个expression为true,因此执行了main分支内容
not:当嵌套条件是错误时,执行这个阶段,必须包含一个条件
下面例子定义环境变量值为100kg,在stage中出现了错误引用为50kg,如图:

环境变量引用错误,因此not条件匹配,将执行steps,jenkins中执行结果如下:

allOf:当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件
下面例子第一个stage中两个条件都正确,第二个只有一个正确,如图:

第一个stage两个条件都正确,因此会打印main分支内容,查看jenkins结果,如图:

anyOf:当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件
下面例子中有个条件为真,一个为假,那么steps将会被执行,如图:

查看jenkins的执行结果,如图:

parameters模块
parameters 指令提供了一个用户在触发流水线时应该提供的参数列表。这些用户指定参数的值可通过 params 对象提供给流水线步骤,可用参数为字符串类型和布尔类型
1、下面例子是字符串类型的参数定义,如图:

通过jenkins第一次构建完,第二次构建的时候就可以看到分支选项,如果多个分支可以选择,如图:

Jenkins运行结果如下:

2、下面例子是布尔类型的参数定义,定义了两个,如图:

在Jenkins界面,第二次构建的时候就可以看到参数选项,可根据需要勾选,如图:

注:parameters里面也可以嵌套gitParameter模块,但是次模块需要安装Git parameter插件
构建前端vue项目
Jenkins按照文章开始的那样配置,Jenkinsfile定义在dev中,代码在main中
涉及插件:
- Git parameter #定义分支,在构建时会显示分支选择
- NodeJS Plugin #执行node命令
- SSH Agent #管理SSH凭据,用于安全的连接远程机器,不支持密码,只能用key
- Publish Over ssh #推送构建结果到远程机器 (好像不装也行)
1、在dev分支中定义Jenkinsfile文件,内容如下:
pipeline {
agent any
tools {
nodejs 'nodejs_10_15_3'
}
environment {
repo = 'git@192.168.238.130:test-project/test-demo.git' //代码位置
//npmrepo = 'https://registry.npmjs.org' //官方npm仓库
npmrepo = 'https://registry.npmmirror.com' //淘宝的npm仓库
GIT_AUTH = 'connect_gitlab' //jenkins连接gitlab的凭据
}
parameters {
gitParameter(
branchFilter: 'origin/(.*)', //过滤以origin开头分支(连接gitlab后会获取全部分支)
defaultValue: 'main', //默认分支
name: 'branch', //参数名,在jenkins界面显示
sortMode: 'NONE', //不对分支进行排序
type: 'PT_BRANCH', //参数类型为分支选择参数
description: '' //分支描述,可不写
)
}
stages {
stage('拉取代码') {
steps {
echo "开始拉取代码"
git (
url: "${env.repo}", //代码仓库,使用evn来获取environment中的值
changelog: true, //是否记录拉取代码时的变更历史,设置为true和false都可以
branch: "${branch}", //制定要拉取的分支
credentialsId: "${env.GIT_AUTH}" //连接gitlab的认证凭据,使用env获取environment的变量
)
}
}
stage('使用node构建'){
steps {
script {
echo '开始构建.....'
sh """
node -v
npm -v
echo "开始执行npm命令构建"
cd "${env.WORKSPACE}" //进入项目目录,固定写法,如果项目为a,那么进入的就是workspace/a目录下
rm -rf node_modules //可选,删不删都行
rm -rf package-lock.json
sudo npm config set registry "${env.npmrepo}" //配置仓库
sudo npm install autoprefixer@latest caniuse-lite@latest browserslist@latest --save-dev //非必须,如果提示版本低就执行这条
sudo npm install --prefer-offline //优先使用本地缓存
sudo npm run build //构建
"""
}
}
}
stage('推送到远程机器上'){
steps {
script {
//sshagent提供一个认证凭据,不支持密码,只支持秘钥
sshagent(credentials: ['66642ff9-35e4-492f-bfdb-bfd84ad984ec']){
sh """
scp -r dist/* root@192.168.238.130:/root //将构建后的推送到远程机器
sleep 1
ssh root@192.168.238.130 "systemctl restart nginx" //执行远程机器重启中间件命令
"""
}
}
}
}
}
}
tools:此次构建使用的工具为nodejs,后面单引号中的nodejs_10_15_3要与Jenkins中配置的一致,查看jenkins中配置,系统管理–全局工具配置–nodejs,如图:

GIT_AUTH:对应的值是jenkins连接gitlab的凭据名称,系统管理–凭据–系统–全局凭据–Add crendentials可添加凭据,选择秘钥,如图:



jenkins所在服务器的公钥要放在gitlab上(头像–>Edit profile–>SSH Keys),如果是docker容器部署的,那就要去容器里获取公钥私钥
注:配置完成后如何Jenkins项目页面还是提示连接gitlab异常,此时可以去Jenkins所在机器(docker部署的就去容器里)使用git clone测试拉取一次,一般测试成功后jenkins界面就可以连接了
gitParameter:需要安装Git parameter插件才能使用
sshagent:用于提供连接远程服务器的认证凭据,不支持密码,只支持秘钥,在jenkins的系统管理–>凭据里配置,将jenkins所在服务器的公钥发送到远程服务器(ssh-copy-id),然后将私钥配置到凭据中(如果是docker部署的就要获取容器中的公钥私钥),配置后如图:

注:sshagent中只能配置凭据ID,不能使用凭据名称,会提示找不到,如果构建后报错内容为:
java.lang.NoSuchMethodError: No such DSL method 'sshagent' found among steps
此错误说明Jenkins的ssh agent插件没有安装,安装下即可
通过http的方式获取代码:
上面的Jenkinsfile使用的是SSH方式获取git代码(git@192.168.2…….git),需要配置公私钥,如果要通过http的方式来获取代码(http://192.168.2…….git),此时就需要使用access tokens了
1、登录gitlab–>头像–>Edit profile–>access token,如图:

填写token名字,勾选权限,如图:

点击创建后即可获取到个人access token,如图:

注:此token要保存好,关闭页面后可能就看不到了
2、登录Jenkins–>系统管理–>凭据–>添加凭据,在密码位置输入token,如图:

配置完成后,页面如图:

在项目界面中连接git的凭据位置,选择刚配置的access_token凭据,如图:

Jenkinsfile中拉取代码的仓库地址要改为http方式的,然后修改凭据为上面配置access_token凭据,如图:

问题:
如果jenkin界面可以看到node版本,但是还是提示node: command not found,可能是权限不足,在npm 命令前面加上sudo即可,如:sudo npm install && sudo npm run build,或者使用绝对路径试试,比如/usr/bin/npm


