<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>

CC BY-SA 4.0
2021-02-16T17:33:57.160Z
2021-02-17T20:30:02.017Z
2021-02-17T20:30:02.017Z
jayhendren
<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>

<jenkins><jenkins-pipeline>
Add stages to Jenkins declarative pipeline through shared library
jpyams
# 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), 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()
        }
      } 
    } 
  } 
}


---

