Answers: <p>Yes, but (to the best of my knowledge) you will have to use Scripted Pipeline within the shared library.  This means that the closure that you will pass to the shared library (in the below example, the closure is <code>sh 'run-tests'</code>) will also have to be Scripted.</p>
  <p><code>Jenkinsfile</code>:</p>
  <pre><code>pipeline {
      agent any
      stages {
          stage('Test') {
              steps {
                  runOnServers {
                      sh 'run-tests'
                  }
              }
          }
          stage('Release') {
              echo 'release'
          }
      }
  }
  </code></pre>
  <p>In your shared library, a file named <code>vars/runOnServers.groovy</code>:</p>
  <pre><code>def call(Closure closure) {
    parallel({
      SanJose: {
        node(&quot;test &amp;&amp; san-jose&quot;) {
          stage('SanJose') {
            closure()
          }
        } 
      },
      Dallas: {
        node('test dallas') {
          stage('Dallas') {
            closure()
          }
        } 
      } 
    } 
  }
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2021-02-16T17:33:57.160Z
Answers: 2021-02-17T20:30:02.017Z
Answers: 2021-02-17T20:30:02.017Z
Answers: jayhendren
Body: <p>Is there a way to write a stage in a Jenkins shared library so that it can be added to declarative pipelines?</p>
  <h1>Background</h1>
  <p>For many projects, I need to run tests on multiple different servers.  My solution is to create a bunch of parallel stages, one for each of the servers that I want to run on.  I've gotten to this pipeline (running on 2 servers as an example):</p>
  <pre><code>pipeline {
      agent any
      stages {
          stage('Test') {
              parallel {
                  stage('San Jose') {
                      agent {
                          label &quot;test &amp;&amp; san-jose&quot;
                      }
                      steps {
                          sh 'run-tests'
                      }
                  }
                  stage('Dallas') {
                      agent {
                          label 'test dallas'
                      }
                      steps {
                          sh 'run-tests'
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  <p>Which is great, but I'd really like to keep my code DRY and not have to copy and paste this Test stage to every project I have (especially since this has to run on about 10 servers, with only the label changing each time).</p>
  <p>I could put the whole pipeline into my shared libary (like <a href="https://www.jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/" rel="nofollow noreferrer">Jenkins's example in the documentation</a>), but then I can't customize the other stages (for example, adding a release stage).</p>
  <p>What I'd really like to do is this:</p>
  <pre><code>pipeline {
      agent any
      stages {
          runOnServers {
              sh 'run-tests'
          }
          stage('Release') {
              echo 'release'
          }
      }
  }
  </code></pre>
  <h1>Question</h1>
  <p>Is there a way I can do this?</p>
  
Tags: <jenkins><jenkins-pipeline>
Title: Add stages to Jenkins declarative pipeline through shared library
UserDisplayName: jpyams
ThreadText: # Add stages to Jenkins declarative pipeline through shared library
  
  (Asked by: username_0 on 2021-02-12)
  
  Is there a way to write a stage in a Jenkins shared library so that it can be added to declarative pipelines?
  
  # Background
  
  For many projects, I need to run tests on multiple different servers. My solution is to create a bunch of parallel stages, one for each of the servers that I want to run on. I've gotten to this pipeline (running on 2 servers as an example):
  
  ```
  pipeline {
      agent any
      stages {
          stage('Test') {
              parallel {
                  stage('San Jose') {
                      agent {
                          label "test && san-jose"
                      }
                      steps {
                          sh 'run-tests'
                      }
                  }
                  stage('Dallas') {
                      agent {
                          label 'test dallas'
                      }
                      steps {
                          sh 'run-tests'
                      }
                  }
              }
          }
      }
  }
  
  ```
  
  Which is great, but I'd really like to keep my code DRY and not have to copy and paste this Test stage to every project I have (especially since this has to run on about 10 servers, with only the label changing each time).
  
  I could put the whole pipeline into my shared libary (like [Jenkins's example in the documentation](https://www.jenkins.io/blog/2017/10/02/pipeline-templates-with-shared-libraries/)), but then I can't customize the other stages (for example, adding a release stage).
  
  What I'd really like to do is this:
  
  ```
  pipeline {
      agent any
      stages {
          runOnServers {
              sh 'run-tests'
          }
          stage('Release') {
              echo 'release'
          }
      }
  }
  
  ```
  
  # Question
  
  Is there a way I can do this?
  
  **Tags:** jenkins, jenkins-pipeline
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-02-16. Score: 1 | Accepted answer
  
  Yes, but (to the best of my knowledge) you will have to use Scripted Pipeline within the shared library. This means that the closure that you will pass to the shared library (in the below example, the closure is `sh 'run-tests'`) will also have to be Scripted.
  
  `Jenkinsfile`:
  
  ```
  pipeline {
      agent any
      stages {
          stage('Test') {
              steps {
                  runOnServers {
                      sh 'run-tests'
                  }
              }
          }
          stage('Release') {
              echo 'release'
          }
      }
  }
  
  ```
  
  In your shared library, a file named `vars/runOnServers.groovy`:
  
  ```
  def call(Closure closure) {
    parallel({
      SanJose: {
        node("test && san-jose") {
          stage('SanJose') {
            closure()
          }
        } 
      },
      Dallas: {
        node('test dallas') {
          stage('Dallas') {
            closure()
          }
        } 
      } 
    } 
  }
  
  ```
  
  
  ---
  
  