Using Building Blocks in Jenkins Declarative Pipeline

浪子不回头ぞ 提交于 2020-08-06 03:06:10

问题


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. Inside vars 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!