I have several microservices which use the same pipeline from a shared library which is named jenkins-shared-pipelines . The Jenkinsfile for a microservice is as follows:
@Library(['jenkins-shared-pipelines']) _
gradleProjectPrPipeline([buildAgent: 'oc-docker-jdk11', disableIntegrationTestStage: true])
In jenkins-shared-pipelines/vars, the gradleProjectPrPipeline has the following stages:
/**
* gradleProjectPrPipeline is a generic pipeline
* @param pipelineProperties map used to pass parameters
* @return
*/
void call(Map pipelineProperties = [:]) {
.
.
.
pipeline {
agent {
node {
label "${pipelineProperties.buildAgent}"
}
}
options {
skipDefaultCheckout true
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(
numToKeepStr: '5',
daysToKeepStr: '7',
artifactNumToKeepStr: '1',
artifactDaysToKeepStr: '7'
))
}
stages {
stage('Clone') {
steps {
//clone step
}
}
stage('Compile') {
steps {
script {
/*Some custom logic*/
}
runGradleTask([task: 'assemble',
rawArgs: defaultGradleArgs + " -Pcurrent_version=${releaseTag}"
])
}
}
stage('Tests') {
parallel {
stage('Unit tests') {
steps {
//Unit tests
}
}
stage('Integration tests') {
steps {
//Integration tests
}
}
}
}
stage('Sonar scan') {
steps {
//Sonar scanning
}
}
}
post {
unsuccessful {
script {
bitbucketHandler.notifyBuildFail([
displayName: pipelineName,
displayMessage: "Build ${env.BUILD_ID} failed at ${env.BUILD_TIMESTAMP}."
])
}
}
success {
script {
bitbucketHandler.notifyBuildSuccess([
displayName: pipelineName,
displayMessage: "Build ${env.BUILD_ID} completed at ${env.BUILD_TIMESTAMP}."
])
}
}
}
}
}
Now, in addition to the above pipeline, there will be several more pipelines in jenkins-shared-pipelines(under the same vars directory) e.g: awsPipeline, azurePipeline and so on which will also incorporate the deployment stages. These additional pipelines will require all the stages in the above gradleProjectBranchWrapper and will also add a few of their own stages. Currently, we simply copy-paste these stages in these additional pipelines,
void call(Map pipelineProperties = [:]) { . . .
pipeline {
agent {
node {
label "${pipelineProperties.buildAgent}"
}
}
options {
skipDefaultCheckout true
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(
numToKeepStr: '5',
daysToKeepStr: '7',
artifactNumToKeepStr: '1',
artifactDaysToKeepStr: '7'
))
}
stages {
stage('Clone') {
steps {
//clone step
}
}
stage('Compile') {
steps {
script {
/*Some custom logic*/
}
runGradleTask([task: 'assemble',
rawArgs: defaultGradleArgs + " -Pcurrent_version=${releaseTag}"
])
}
}
stage('Tests') {
parallel {
stage('Unit tests') {
steps {
//Unit tests
}
}
stage('Integration tests') {
steps {
//Integration tests
}
}
}
}
stage('Sonar scan') {
steps {
//Sonar scanning
}
}
stage('AWS'){
}
}
post {
unsuccessful {
script {
bitbucketHandler.notifyBuildFail([
displayName: pipelineName,
displayMessage: "Build ${env.BUILD_ID} failed at ${env.BUILD_TIMESTAMP}."
])
}
}
success {
script {
bitbucketHandler.notifyBuildSuccess([
displayName: pipelineName,
displayMessage: "Build ${env.BUILD_ID} completed at ${env.BUILD_TIMESTAMP}."
])
}
}
}
}
}
then, we invoke these new pipelines from the microservices, so for example:
@Library(['jenkins-shared-pipelines']) _
awsPipeline([buildAgent: 'oc-docker-jdk11', disableIntegrationTestStage: true])
As obvious, there is code redundancy as the clone to sonarScan stages are common but there is no 'base pipeline' or another way to include these common stages in all the pipelines. I was wondering if there is a way to 'include' the gradleProjectPrPipeline(which can serve as a 'base pipeline') the pipelines like awsPipeline, azurePipeline and so on. Note:
- The workspace(where the clone stag checks out the code and later stages operate) will be used by awsPipeline etc. In other words, the variables and results from the gradleProjectBranchWrapper should be accessible to the awsPipeline etc.
- There is a post block in the gradleProjectBranchWrapper, the other pipelines may have their own post blocks