How to set and reference a variable in a Jenkinsfi

2019-03-23 01:39发布

I have a declarative pipeline script for my multibranch project in which I would like to read a text file and store the result as a string variable to be accessed by a later step in the pipeline. Using the snippet generator I tried to do something like this:

filename = readFile 'output.txt'

For which filename would be my string.

I get an error in the Jenkins console output:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 30: Expected a step @ line 30, column 5.
            filename = readFile 'output.txt'

Do I need to use a withEnv step to set the output of readFile to a Jenkins environment variable? If so, how?

Thanks

5条回答
▲ chillily
2楼-- · 2019-03-23 02:03

The error is due to that you're only allowed to use pipeline steps inside the steps directive. One workaround that I know is to use the script step and wrap arbitrary pipeline script inside of it and save the result in the environment variable so that it can be used later.

So in your case:

pipeline {
    agent any
    stages {
        stage("foo") {
            steps {
                script {
                    env.FILENAME = readFile 'output.txt'
                }
                echo "${env.FILENAME}"
            }
        }
    }
}
查看更多
乱世女痞
3楼-- · 2019-03-23 02:03

A complete example for scripted pipepline:

       stage('Build'){
            withEnv(["GOPATH=/ws","PATH=/ws/bin:${env.PATH}"]) {
                sh 'bash build.sh'
            }
        }
查看更多
做个烂人
4楼-- · 2019-03-23 02:14

According to the documentation, you can also set global environment variables if you later want to use the value of the variable in other parts of your script. In your case, it would be setting it in the root pipeline:

pipeline {
  ...
  environment {
    FILENAME = readFile ...
  }
  ...
}
查看更多
看我几分像从前
5楼-- · 2019-03-23 02:19

I can' t comment yet but, just a hint: use try/catch clauses to avoid broke the pipeline (if you are sure the file exists, disregard)

    pipeline {
        agent any
            stages {
                stage("foo") {
                    steps {
                        script {
                            try {                    
                                env.FILENAME = readFile 'output.txt'
                                echo "${env.FILENAME}"
                            }
                            catch(Exception e) {
                                //do something i.e echo 'File not found'
                            }
                        }
                   }
    }

Another hint (this was commented by @hao, and i think is worth to share): you may want to trim like this readFile('output.txt').trim()

查看更多
Juvenile、少年°
6楼-- · 2019-03-23 02:21

We got around this by adding functions to the environment step, i.e.:

environment {
    ENVIRONMENT_NAME = defineEnvironment() 
}
...
def defineEnvironment() {
    def branchName = "${env.BRANCH_NAME}"
    if (branchName == "master") {
        return 'staging'
    }
    else {
        return 'test'
    }
}
查看更多
登录 后发表回答