• 对于注定会优秀的人来说,他所需要的,只是时间!
  • 手懒得,必受贫穷,手勤的,必得富足----《圣经》
  • 帮助别人,成就自己。愿君在本站能真正有所收获!
  • 如果你在本站中发现任何问题,欢迎留言指正!
  • 宝剑锋从磨砺出,梅花香自苦寒来!

<四十一>Jenkins实战应用–pipeline中如何在environment环节声明一个含有通配符的变量

Jenkins eryajf 3个月前 (07-06) 476°C 已收录 0个评论
本文预计阅读时间 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之前声明这个变量,然而发现总是会失败,也许是我声明的方式不大对吧,后来还是在官网看到了一个优雅的方案,官方示例如下:

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'
            }
        }
    }
}

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

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

其中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)
              }
          }
          } 
      }
    }
    
  • 2,有一个奇怪的坑是,当我将变量传给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()}"""
              }
    

weinxin
扫码订阅本站,第一时间获得更新
微信扫描二维码,订阅我们网站的动态,另外不定时发送WordPress小技巧,你可以随时退订,欢迎订阅哦~

二丫讲梵 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明<四十一>Jenkins实战应用–pipeline中如何在environment环节声明一个含有通配符的变量
喜欢 (0)
[如果想支持本站,可支付宝赞助]
分享 (0)
eryajf
关于作者:
学无止境,我愿意无止境学。书山有路,我愿意举身投火,淬炼成金!永远不要忘记,激情的奋进,就是美好的未来!

您必须 登录 才能发表评论!