8

Jenkins实战应用–pipeline中如何在environment环节声明一个含有通配符的变量 |坐而言...

 3 years ago
source link: http://www.eryajf.net/5140.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Jenkins实战应用–pipeline中如何在environment环节声明一个含有通配符的变量 |坐而言不如起而行! 二丫讲梵
> 术业专攻 > 自动化运维 > Jenkins > <四十一>Jenkins实战应用–pipeline中如何在environment环节声明一个含有通配符的变量
本文预计阅读时间 7 分钟

先来简述一下需求以及思路吧:

我这边拉代码编译以及准备工作都是基于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之前声明这个变量,然而发现总是会失败,也许是我声明的方式不大对吧,后来还是在官网看到了一个优雅的方案,官方示例如下:

  1. pipeline {
  2. agent any
  3. environment {
  4. // 使用 returnStdout
  5. CC = """${sh(
  6. returnStdout: true,
  7. script: 'echo "clang"'
  8. )}"""
  9. // 使用 returnStatus
  10. EXIT_STATUS = """${sh(
  11. returnStatus: true,
  12. script: 'exit 1'
  13. )}"""
  14. }
  15. stages {
  16. stage('Example') {
  17. environment {
  18. DEBUG_FLAGS = '-g'
  19. }
  20. steps {
  21. sh 'printenv'
  22. }
  23. }
  24. }
  25. }

我赶忙创建一个项目运行一下看,果不其然,在环境变量中,CC=clangEXIT_STATUS=1,一例惊醒梦中人,我于是定义了如下变量:

  1. environment {
  2. // 定义项目编译完成之后的包文件
  3. project_file="""${sh(returnStdout: true, script: "echo $WORKSPACE/${project}/target/${project}-*.jar")}"""
  4. }

其中project定义在全局的变量中。

最后果然输出了自己想要的内容。

71cfeb93ly1gf8janlqxjj21ct1z4n82.jpg

经过几个项目的体验,简单总结有如下几个注意点:

  • 1,此声明不要放在开头的全局变量中,而应该在具体构建的stage中,不然变量的值将会是上次构建的包名,而非当次包名。示例如下:
    1. stage('部署<向左') {
    2. environment {
    3. // 定义项目编译完成之后的包文件
    4. project_file="""${sh(returnStdout: true, script: "echo $WORKSPACE/${project}/target/${project}-*.jar")}"""
    5. }
    6. when {
    7. environment name: 'mode',value: 'deploy'
    8. }
    9. steps {
    10. dir("$ansible_base"){
    11. script {
    12. try {
    13. sh '''
    14. 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}
    15. '''
    16. }catch(exc) {
    17. Reason = "项目部署步骤出错"
    18. throw(exc)
    19. }
    20. }
    21. }
    22. }
    23. }
  • 2,有一个奇怪的坑是,当我将变量传给playbook时,如果project_file这个变量靠前,则后边的变量会被忽略(暂未经过更多验证),于是就把这个变量放在最后传了。
  • 3,后来又集成进来一项参数,就是Java应用的启动参数,这个特殊之处在于中间有空格,尝试了许多种方案,最终发现这个方案能够保证参数不是断开的。但是使用过程中始终发现会有问题,事实上那篇文章地下有说明,使用.trim()方法可以避开:

    1. environment {
    2. // 定义项目编译完成之后的包文件
    3. project_file="""${sh(returnStdout: true, script: "echo ${jar_file}").trim()}"""
    4. // 指定服务启动参数, .trim() 去除末尾的空格
    5. start_params="""${sh(returnStdout: true, script: "echo ${start_param}").trim()}"""
    6. }

weinxin


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK