pipeline中如何在environment环节声明一个含有通配符的变量
先来简述一下需求以及思路吧:
我这边拉代码编译以及准备工作都是基于Jenkinsfile
完成,然后再基于ansible-playbook
进行构建或者回滚,在调用playbook
的时候会将提取出来的变量传进去,其中一个变量定义了项目打包之后的 jar 包的绝对路径。不同项目可能这个路径规范不一致,即便是同一项目,可能也会时常变更版本(比如admin-0.0.1.jar
,下次可能会是admin-0.0.2.jar
),从而无法写成固定的变量。
比较容易的一个办法是利用通配符来匹配这个包,那么可以定义成 project_file=$WORKSPACE/${project}/target/${project}-*.jar
,以使得这个变量具有更强的兼容性。
但是当我兴致冲冲地将在全局environment
区块中声明了如上变量后,便立刻点击了构建。然而却发现程序并没有解析通配符,传递下去的值变成了admin-*.jar
,于是我开始寻觅能够解决这一尴尬的方案。
一开始打算直接在调用 ansible 之前声明这个变量,然而发现总是会失败,也许是我声明的方式不大对吧,后来还是在官网 (opens new window)看到了一个优雅的方案,官方示例如下:
pipeline {
agent any
environment {
// 使用 returnStdout
CC = """${sh(
returnStdout: true,
script: 'echo "clang"'
)}"""
// 使用 returnStatus
EXIT_STATUS = """${sh(
returnStatus: true,
script: 'exit 1'
)}"""
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
我赶忙创建一个项目运行一下看,果不其然,在环境变量中,CC=clang
,EXIT_STATUS=1
,一例惊醒梦中人,我于是定义了如下变量:
environment {
// 定义项目编译完成之后的包文件
project_file="""${sh(returnStdout: true, script: "echo $WORKSPACE/${project}/target/${project}-*.jar")}"""
}
2
3
4
其中 project 定义在全局的变量中。
最后果然输出了自己想要的内容。
经过几个项目的体验,简单总结有如下几个注意点:
1,此声明不要放在开头的全局变量中,而应该在具体构建的 stage 中,不然变量的值将会是上次构建的包名,而非当次包名。示例如下:
stage('部署<向左') { environment { // 定义项目编译完成之后的包文件 project_file="""${sh(returnStdout: true, script: "echo $WORKSPACE/${project}/target/${project}-*.jar")}""" } when { environment name: 'mode',value: 'deploy' } steps { dir("$ansible_base"){ script { try { sh ''' ansible-playbook -i ./deploy_hosts/${JOB_NAME}_hosts --tags "deploy,${project}" site.yml -e "project"=$project -e "_version"=${_version} -e "JOB_NAME"=${JOB_NAME} -e "remote_host"=${remote_host} -e "server_port"=${server_port} -e project_env=${project_env} -e project_user=${project_user} -e start_Xms=${start_Xms} -e start_Xmx=${start_Xmx} -e "project_file"=${project_file} ''' }catch(exc) { Reason = "项目部署步骤出错" throw(exc) } } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
232,有一个奇怪的坑是,当我将变量传给 playbook 时,如果 project_file 这个变量靠前,则后边的变量会被忽略(暂未经过更多验证),于是就把这个变量放在最后传了。
3,后来又集成进来一项参数,就是 Java 应用的启动参数,这个特殊之处在于中间有空格,尝试了许多种方案,最终发现这个方案能够保证参数不是断开的。但是使用过程中始终发现会有问题,事实上那篇文章地下有说明,使用
.trim()
方法可以避开:environment { // 定义项目编译完成之后的包文件 project_file="""${sh(returnStdout: true, script: "echo ${jar_file}").trim()}""" // 指定服务启动参数, .trim() 去除末尾的空格 start_params="""${sh(returnStdout: true, script: "echo ${start_param}").trim()}""" }
1
2
3
4
5
6