问题
I'm just starting with using Jenkins declarative pipelines. As I'm supporting a few similar projects I was thinking of putting similar pipeline steps (or even stages) into reusable building blocks. These blocks should be maintained at a central spot and then included by individual pipelines (speak: DRY).
I saw shared libraries as an option for scripted pipelines but I'm not sure if it works for declarative pipelines, too.
Do you know a way to use something like building blocks in Jenkins declarative pipelines?
Example to clarify:
If you got a standard pipeline for Maven projects (e. g. Spring Boot), it looks somewhat like:
pipeline {
agent {
dockerfile true
}
stages {
stage('Build') {
steps {
sh 'mvn -U -DskipTests clean package'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'mvn test'
}
}
stage('Integration Tests') {
steps {
sh 'mvn integration-test'
}
}
}
}
stage('Deploy') {
steps {
sh 'mvn deploy'
}
}
}
}
But instead of copying this to all projects, it would be great if following use cases could be easy handled.
For a project without need to customize it would be good to use it for examle like:
defaultMavenpipeline{}
where defaultMavenpipeline
will be replaced by above pipeline (I think this is possible with shared libraries).
For a project with need to customize only some stages would something like this be possible?
pipeline {
defaultDockerAgent{}
stages {
stage('Build') {
steps {
sh 'mvn -U -DskipTests clean package'
// ... customize some stuff ...
}
}
defaultTestStage{}
stage('Deploy') {
steps {
// ... customize some stuff ...
sh 'mvn deploy'
}
}
}
}
Sorry for long post and thank you very much in advance!
回答1:
You can very much use declarative pipeline with Shared-Library.
Please follow these steps:
1) Create a shared library
- Create a repository shared-lib
- Create a directory named
vars
in above repository. Insidevars
directory, create a file sayHello.groovy with the following content:
// vars/sayHello.groovy
def call(String name = 'human') {
// Any valid steps can be called from this code.
// Can be used in both scripted and declarative pipeline
echo "Hello, ${name}."
}
2) Configure Jenkins for accessing Shared Library in any pipeline job
- Go to Manage Jenkins » Configure System » Global Pipeline Libraries section
- Name the library whatever you want (in my case, my-shared-library as shown below)
- Add the branch name that contains your Groovy code. In my case, it was in the default branch i.e.,
master
- No need to check/uncheck the check-boxes unless you know what you're doing
3) Access shared library in your project
- In Jenkinsfile or
Pipeline script
section, add the following code:
@Library('my-shared-lib')_
pipeline {
agent any
stages {
stage('Info') {
steps {
echo 'Publishing some details here'
}
}
stage('Using shared-library') {
steps {
sayHello 'Alex'
}
}
}
}
That's it. You're done! :)
Note: For the the underscore (_
) used in shared-library above in Jenkinsfile, from official link, for Shared Libraries which only define Global Variables (vars/
), or a Jenkinsfile which only needs a Global Variable, the annotation pattern @Library('my-shared-library') _
may be useful for keeping code concise. In essence, instead of annotating an unnecessary import statement, the symbol _
is annotated.
Output:
回答2:
You can use shared libraries for that.
I use vars section in the library to define a template (workflow) , src section to write classes with reusable methods and from the jenkinsfile I am only calling the template providing it with a map of parameters which are project specific.
This allows me to leave the dev to make their own projects only by cloning them and altering the jenkinsfile while I still have control of the execution.
in jenkinsfile:
@Library('jenkinssharedlibrary') _
templatename([
parameter1: "value",
parameter2: "value"])
in shared library : vars/templatename.groovy
import com.mydomain.someclassivemade
def call(Map<String, String> passedConfig) {
Myclass niceobject = new Myclass()
pipeline {
agent {
label 'test'
}
environment {
PROJECT_VERSION = "${passedConfig.version}"
}
tools {
jdk '....'
}
stages {
steps {
script {
niceobject.compile(mvn)
}
}}
}
in the src folder you write your classes with methods to reuse: /src/com/mydomain/Someclassivemade.groovy
package com.mydomain.someclassivemade
def build (final String xyz){
sh("build comand with parameters")
}
return this // very important line :)
In a simpler approach you can put your methods in vars and call them from your jenkinsfile. Jenkins's power is in it's flexibility.
another useful link
PS: I might have syntax errors as I wrote directly here , please tell me to fix them !
来源:https://stackoverflow.com/questions/62190395/using-building-blocks-in-jenkins-declarative-pipeline