Answers: <p>You should look at <a href="https://jenkins.io/doc/book/pipeline/shared-libraries/#global-shared-libraries" rel="noreferrer">Global Shared Libraries</a>, which will allow you to reuse logic across different Jenkinsfiles.</p>
  
  <p>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 <a href="https://github.com/lesfurets/JenkinsPipelineUnit" rel="noreferrer">unit test</a> them using </p>
  
Answers: CC BY-SA 3.0
Answers: 2017-09-07T06:45:44.300Z
Answers: 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!
Answers: Adam
Answers: CC BY-SA 3.0
Answers: 2017-09-06T18:35:35.410Z
Answers: 2017-09-06T18:35:35.410Z
Answers: Michael Pereira
Answers: <p>I also have the same idea(different config files for different pipeline).
  I use the pipeline.properties to store my variable. </p>
  
  <pre><code>properties = readProperties file: 'pipeline.properties'
  echo "Immediate one ${properties.repo}"
  </code></pre>
  
  <p><strong>Drawbacks:</strong>
  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).</p>
  
  <p>See:
  <a href="https://stackoverflow.com/questions/46630168/in-a-declarative-jenkins-pipeline-can-i-set-the-agent-label-dynamically">https://stackoverflow.com/questions/46630168/in-a-declarative-jenkins-pipeline-can-i-set-the-agent-label-dynamically</a></p>
  
  <p><a href="http://jenkins-ci.361315.n4.nabble.com/can-i-use-variable-to-specify-the-agent-label-in-my-declarative-pipeline-td4897177.html" rel="nofollow noreferrer">http://jenkins-ci.361315.n4.nabble.com/can-i-use-variable-to-specify-the-agent-label-in-my-declarative-pipeline-td4897177.html</a></p>
  
Answers: CC BY-SA 3.0
Answers: 2018-02-01T07:57:13.497Z
Answers: 2018-02-01T07:57:13.497Z
Answers: Xuezhong
Body: <p>Right now we have many projects with similar Jenkinsfile's. Instead of <em>copypasting</em> 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 <strong>channel</strong>, <strong>bot token</strong>, and some <strong>fixed text</strong> are always the same.</p>
  
  <p>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 <em>"constant"</em> parameters.</p>
  
  <p>We tried putting a <code>config.json</code> and using the readJSON step like this:</p>
  
  <pre><code>def load(path) {
      env.CONFIGURATION =  readJSON(file: path)
  }
  </code></pre>
  
  <p>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 <code>env.CONFIGURATION.slack.channel</code> for example)</p>
  
  <p>We tried the following also in <strong>Jenkinsfile</strong>:</p>
  
  <pre><code>def CONFIG = readJSON(file: path)
  </code></pre>
  
  <p>But CONFIG then is not visible inside the library scripts.</p>
  
  <p>So now, the questions:</p>
  
  <ol>
  <li><p>Is our approach correct? Putting all common config in one file and
  loading it for the library scripts to see.</p></li>
  <li><p>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?</p></li>
  </ol>
  
  <p>Thanks in advance for your help.</p>
  
Tags: <jenkins><jenkinsfile><groovy>
Title: Jenkins libraries configuration in Jenkinsfile
UserDisplayName: Adam
ThreadText: # Jenkins libraries configuration in Jenkinsfile
  
  (Asked by: username_0 on 2017-09-06)
  
  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.
  
  **Tags:** jenkins, jenkinsfile, groovy
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2017-09-06. Score: 5
  
  You should look at [Global Shared Libraries](https://jenkins.io/doc/book/pipeline/shared-libraries/#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](https://github.com/lesfurets/JenkinsPipelineUnit) them using
  
  > **Comments:**
  > **username_0**: 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!  
  
  ---
  
  ### Answer by username_2 on 2018-02-01. Score: 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>
  
  
  ---
  
  