学习和使用 jenkins pipeline 过程中遇到的问题和解决办法
shell 脚本进程被杀问题

自 1.260 版本开始,Jenkins 默认会在构建完成后杀死构建过程中由 jenkins 中的 shell 命令触发的衍生进程ProcessTreeKiller: https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller](https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller)
方法一
修改配置,启动 jenkins 时禁止其杀死衍生进程:vim /etc/sysconfig/jenkins
在 JENKINS_JAVA_OPTIONS 中加入 -Dhudson.util.ProcessTree.disable=true
重启 jenkins 生效:systemctl restart jenkins 
方法二:
Pipeline:设置 JENKINS_NODE_COOKIE 参数的值:
withEnv(['JENKINS_NODE_COOKIE=dontkillme']) {
sh 'sh ${tomcatHome}/bin/startup.sh'
}
非 Pipeline:
在执行 shell 输入框中加入
BUILD_ID=dontKillMe,即可防止 jenkins 杀死启动的进程临时改变 BUILD_ID 值,使得 jenkins 不会找到并结束掉 run.sh 启动的后台进程
OLD_BUILD_ID=$BUILD_ID
echo $OLD_BUILD_ID
export BUILD_ID=dontKillMe
# 执行 tomcat 启动脚本
sh ${tomcat}/bin/startup.sh
# 改回原来的 BUILD_ID 值
export BUILD_ID=$OLD_BUILD_ID
echo $BUILD_ID
node:未找到命令
使用 sonar 扫描项目时报警告:

发现服务器上未装NodeJS,但是装好后 Jenkins 内执行 shell 命令无法获取环境变量

于是搜索一番后找到原因:https://blog.csdn.net/zzusimon/article/details/57080337
(1) 可以通过-i参数和-l参数让 bash 为 login shell and interactive shell,就可以读取/etc/profile和~/.bash_profile等文件,即在 jenkins Execute Shell 里可以这么写
#!/bin/bash -ilex
...
...
对于 e 参数表示一旦出错,就退出当前的 shell,x 参数表示可以显示所执行的每一条命令
(2)使用流水线语法生成脚本,将需要调用 NodeJS 的 shell 命令写在括号内:

测试成功:


构建超时自动停止
在 pipeline 设置超时时间,超过该限制时会中断 pipeline 的执行
// 方式一:在 pipeline 中配置
pipeline {
options{
timeout(time:15, unit:'SECONDS')
}
stages { .. }
// ..
}
// 方式二:在 stage 中配置
pipeline {
agent any
stages {
stage('Run') {
steps {
retry(3) {
sh './deploy.sh'
}
timeout(time: 3, unit: 'MINUTES') {
sh './ren_test.sh'
}
}
}
}
maven 类型项目在构建环境下配置,勾选 Abort the build if it’s stuck

在 pipeline 中触发其他 job
在项目构建前需要先构建项目 test-common,可以在 pipeline 进行配置
// 放在 stages 下,变量用双引号
stage('ltprivate-center-common') {
steps {
timeout(time: 30, unit: 'SECONDS') {
script{
echo "正在构建 test-common, 分支:${params.branch}"
build job :'test-common', parameters:[string(name: 'branch', value: "${params.branch}")]
echo "完成构建"
}
}
}
}
when 指令的使用
when 指令位于stage指令中,允许 pipeline 根据给定的条件决定是否应该执行阶段,必须包含至少一个条件
例:buildType为Choice Parameter参数,当选择 deploy 进行构建时,只会执行满足条件的 stage
pipeline {
agent any
stages {
stage('更新') {
when { environment name: 'buildType', value: 'deploy' }
steps {
echo "更新完成"
}
}
stage('回滚') {
when { environment name: 'buildType', value: 'rollback' }
steps {
echo "回滚更新完成"
}
}
}
}
控制台输出
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /data/.jenkins/workspace/测试目录/webhook-common
[Pipeline] {
[Pipeline] stage
[Pipeline] { (更新)
Stage "更新" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (回滚)
[Pipeline] echo
回滚更新完成
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
其它使用条件
changelog:
when { changelog '.*^\\[DEPENDENCY\\] .+$' },构建的SCM变更日志包含一个给定的正则表达式模式,则执行该阶段anyOf:
when { anyOf { branch 'master'; branch 'staging' } },当至少有一个嵌套条件为true时执行,必须包含至少一个条件https://blog.csdn.net/a772304419/article/details/132456478
input 指令的使用
input 允许用户在执行各个 stage 时由人工确认是否继续进行,官网 input 语法:https://www.jenkins.io/doc/book/pipeline/syntax/#input,input 书写方式有以下两种
- message 呈现给用户的提示信息
- id 可选,默认为stage名称
- ok 默认表单上的 ok 文本
- submitter 可选,以逗号分隔的用户列表或允许提交的外部组名。默认允许任何用户
- submitterParameter 环境变量的可选名称。如果存在,用submitter 名称设置
- parameters 提示提交者提供的一个可选的参数列表
方式一
input 与 steps 同级
pipeline {
agent any
stages {
stage('更新') {
when { environment name: 'buildType', value: 'deploy' }
steps {
echo "更新完成"
}
}
stage('回滚') {
when {
beforeInput false
environment name: 'buildType', value: 'rollback'
}
input {
message "是否继续回退更新?"
ok "继续"
parameters {
string(name: 'history_number', defaultValue: 'lastVersion', description: '请输入回退更新的历史构建编号,回退到上个版本使用:lastVersion')
}
}
steps {
script {
echo "history_number: ${env.history_number},回滚完成"
}
}
}
}
}
PS:当 when 和 input 同时使用时需要在 when 内增加
beforeInput true,此时when条件将首先计算,只有当条件计算为 true 时才会进入input,默认情况下 beforeInput 为 false以上述流水线为例,beforeInput 为 false,input 会在 when 之前执行,因此选择 deploy 构建时,流水会卡在 input 处
方式二
input 在 steps 内部
pipeline {
agent any
stages {
stage('更新') {
when { environment name: 'buildType', value: 'deploy' }
steps {
echo "更新完成"
}
}
stage('回滚') {
when { environment name: 'buildType', value: 'rollback' }
steps {
script {
timeout(time: 5, unit: 'SECONDS') {
def inputResult = input message: "是否继续回退更新?", ok: "继续", parameters: [
string(name: 'history_number', defaultValue: 'lastVersion', description: '请输入回退更新的历史构建编号,回退到上个版本使用:lastVersion')
]
}
echo "history_number: ${inputResult},回滚完成"
}
}
}
}
}
构建失败时通知
使用企业微信机器人通知,官网 post 语法:https://www.jenkins.io/doc/book/pipeline/syntax/#post

pipeline {
agent any
stages {
stage('检出') {
steps {
script{
// 将当前构建结果设置为失败
currentBuild.result = "FAILURE"
}
}
}
}
post{
// success{}
// 构建失败时发送通知
failure{
sh '''curl -s -H "Content-Type: application/json" -X POST -d \'{
"msgtype": "markdown",
"markdown": {
"content": "<font color=\\"warning\\">**Jenkins任务通知**</font> \\n
>构建编号:<font color=\\"comment\\">\'"${BUILD_DISPLAY_NAME}"\'</font>
>任务名称:<font color=\\"comment\\">\'"${JOB_BASE_NAME}"\'</font>
>构建分支:<font color=\\"comment\\">\'"${branch}"\'</font>
>构建状态:<font color=\\"comment\\">Failure</font>"
}
}\' \'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx\''''
}
}
}
Generic Webhook Trigger 配置

过滤条件:仅当 test-admin目录下的文件被 push 时,触发构建

修改默认触发时间:https://www.cnblogs.com/huandada/p/13067778.html
- 本文作者:Nine
- 本文链接:https://blog.nine.gt.tc/wiki/tools-cicd-pipeline/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
