5

Right now we have many projects with similar Jenkinsfile's. Instead of copypasting we're developing a shared library with some utilities. This library is loaded dynamically in each Jenkinsfile, and has some parameters that repeat among calls. For example, an utility has a custom Slack message posting function, and the channel, bot token, and some fixed text are always the same.

Instead of providing those parameters to every call to this Slack function we have thought of making a config file and loading it globally at the beginning with all these "constant" parameters.

We tried putting a config.json and using the readJSON step like this:

def load(path) {
    env.CONFIGURATION =  readJSON(file: path)
}

So the CONFIGURATION is an environment variable and so it's global. The problem is that it seems that environment variables can only be strings, so the JSON is broken (we cannot do env.CONFIGURATION.slack.channel for example)

We tried the following also in Jenkinsfile:

def CONFIG = readJSON(file: path)

But CONFIG then is not visible inside the library scripts.

So now, the questions:

  1. Is our approach correct? Putting all common config in one file and loading it for the library scripts to see.

  2. If it's not correct, how would you deal with our problem? Simply passing the config as parameter on every call and that's all?

Thanks in advance for your help.

5

You should look at Global Shared Libraries, which will allow you to reuse logic across different Jenkinsfiles.

Rather than depending on the environment, it's probably safer to explicitly pass parameters and returns values from the functions, which will make their behavior more explicit. Another side benefit is that you will be able to unit test them using

  • Thanks for you response! In fact we're already developing shared libraries. We could use Global ones but our Jenkins is managed by other team, and it has also a lot of dev teams involved that don't require our libraries :( So that's why we load them dynamically. We'll definitely try that unit testing framework. Regarding config, we'll try that approach if we don't find any other solution. Thanks again! – Adam Barreiro Sep 7 '17 at 6:45
1

I also have the same idea(different config files for different pipeline). I use the pipeline.properties to store my variable.

properties = readProperties file: 'pipeline.properties'
echo "Immediate one ${properties.repo}"

Drawbacks: Due to the groovy early evaluation problems. The value will be null when you use the ${properties.repo} in some shared library closure (eg, agent { label $properties.agentLabel }, the agentLabel will be null).

See: https://stackoverflow.com/questions/46630168/in-a-declarative-jenkins-pipeline-can-i-set-the-agent-label-dynamically

http://jenkins-ci.361315.n4.nabble.com/can-i-use-variable-to-specify-the-agent-label-in-my-declarative-pipeline-td4897177.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.