在声明性Jenkins脚本块中,执行命令时应如何引用变量?

时间:2019-01-16 06:30:40

标签: continuous-integration jenkins-pipeline

我正在将Jenkins声明式管道用于无服务器应用程序。 试图通过创建函数来抽象逻辑。但是当执行命令“ sam deploy --template-file packaged.yaml --stack-name stackname”时,我被困在引用函数变量“ stackname”。

我的代码的TLDR版本如下:

    stages {
        stage('Deploy') {
            steps {
                echo '[STAGE] Deploying...'
                //switch to each lambda sub-folder as working directory
                dir ("${env.WORKSPACE}") {
                    deployAllProject("my-test-stack")
                }
            }
        }
    }

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket my-lambda-midway'
    sh 'sam deploy --template-file packaged.yaml --stack-name stackname'
}

我尝试了不同的变量语法,例如。 $ stackname,$ {stackname}也尝试将其括在Script块中。 这是代码的更完整版本:

def LAMBDA_BUILD_LIST = "dailybackup-ebs-volumes,dailybackup-ebs-volumes-test"
def CLOUDFORMATION_STACK = "DEVOPS-serverless-apps"
def LAMBDAS

pipeline {

    agent {
        node {
            label 'docker'
        }
    }

    stages {
        //checkout scm in defined through Jenkins console

        stage('Init'){
            steps {
                echo "[STAGE] Init..."

                script {

                    // init variables
                    LAMBDAS = splitStringWithComma(LAMBDA_BUILD_LIST)

                    // check lambda sub-folders exist
                    for(String lambda: LAMBDAS) {
                        def var_lambda_dir = "${env.WORKSPACE}/${lambda}"
                        if (!fileExists(var_lambda_dir)) {
                            println("[WARNING]"+ var_lambda_dir +" does not exist.")
                        }
                    }
                }
            }
        }
        stage('Build') {
            steps {
                echo '[STAGE] Building...'

                script {
                    for(String lambda: LAMBDAS) {
                        println("lambda is:"+lambda)
                        def var_lambda_dir = "${env.WORKSPACE}/${lambda}"

                        //switch to each lambda sub-folder as working directory 
                        dir (var_lambda_dir) {
                            buildNodejsProject()
                        }
                    }
                }
            }
        }
        stage('Deploy') {
            steps {
                echo '[STAGE] Deploying...'
                //switch to each lambda sub-folder as working directory
                dir ("${env.WORKSPACE}") {
                    //TODO change hardcoded to variable 'CLOUDFORMATION_STACK'
                    deployAllProject("my-test-stack")
                }
            }
        }
    }
}

/*
 * Transform a comma delimited String into a String list/array
*/
def splitStringWithComma(projects){
    println ("splitStringWithComma() - result: "+projects.split(","))

    return projects.split(",")
}

/*
 * Build lambda functions
*/
void buildNodejsProject(){
    sh 'npm prune'
    sh 'npm install'
}

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket my-lambda-midway'
    sh 'sam deploy --template-file packaged.yaml --stack-name stackname'
}

我想我一定已经忽略了一些基本语法,但是只是找不到正确的关键字。请向我推荐一种处理变量的好方法,并指出我应该关注的官方文档部分。在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我找到了一个帖子,可以帮助我解决此问题。 How to pass variables from Jenkinsfile to shell command

但是我仍然不知道我先前写的和下面使用的可行解决方案之间的核心区别是什么。

感谢ppl阅读这篇文章。如果您有更好的解决方法,或者可以指出我应该阅读的文档,请投票! TA

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket bc-lambda-midway'
    sh """
        sam deploy --template-file packaged.yaml --stack-name ${stackname}
    """
}