如何在environment中声明一个含有通配符的变量

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

我这边拉代码编译以及准备工作都是基于Jenkinsfile完成,然后再基于ansible-playbook进行构建或者回滚,在调用plaubook的时候会将提取出来的变量传进去,其中一个变量定义了项目打包之后的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=clang,EXIT_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这个变量靠前,则后边的变量会被忽略(暂未经过更多验证),于是就把这个变量放在最后传了。

1赞