Every team I have worked with starts with a Jenkinsfile copied from the last project. Six months later there are forty slightly different pipelines, and a single change to the security scan step means forty pull requests. A Jenkins shared library fixes this: the pipeline logic lives in one Git repo, and each application keeps a five-line Jenkinsfile.
Repository layout
jenkins-shared-lib/
├── vars/
│ ├── javaPipeline.groovy // full pipeline for Maven/Spring Boot apps
│ ├── nodePipeline.groovy
│ └── dockerBuild.groovy // reusable step
├── src/org/shailapps/ci/
│ └── Utils.groovy // plain Groovy helpers
└── resources/
└── templates/sonar-project.properties
- vars/ – global steps. The file name becomes the step name (
javaPipeline()). - src/ – normal Groovy classes, imported with
import org.shailapps.ci.Utils. - resources/ – static files, loaded with
libraryResource 'templates/sonar-project.properties'.
A pipeline as a step
// vars/javaPipeline.groovy
def call(Map cfg = [:]) {
def jdk = cfg.get('jdk', 'jdk21')
def image = cfg.get('image', env.JOB_BASE_NAME)
pipeline {
agent { label 'linux' }
tools { jdk jdk; maven 'maven3' }
options { timestamps(); disableConcurrentBuilds() }
stages {
stage('Build & Test') {
steps { sh 'mvn -B clean verify' }
post { always { junit '**/target/surefire-reports/*.xml' } }
}
stage('Sonar') {
steps { withSonarQubeEnv('sonar') { sh 'mvn -B sonar:sonar' } }
}
stage('Image') {
when { branch 'main' }
steps { dockerBuild(name: image) }
}
}
}
}
The application side
@Library('jenkins-shared-lib@v1.4.0') _
javaPipeline(jdk: 'jdk21', image: 'account-search')
That is the whole Jenkinsfile. Register the library once under Manage Jenkins → System → Global Pipeline Libraries with the name jenkins-shared-lib and your Git URL.
Lessons learned
- Pin versions. Reference a tag (
@v1.4.0), not@main. A broken commit on main should not break every build in the company at once. - Keep config in maps. Pass options as a
Mapwith sensible defaults, so adding a new option never breaks existing callers. - Test the library. Use the JenkinsPipelineUnit framework to unit-test your
vars/steps before tagging a release. - One sample project per stack. Keep a tiny Java, Node and Python sample repo that runs the latest library version nightly. It is the cheapest early warning you will ever get.
Once the library is in place, adding a new scan or a new deploy target becomes one pull request instead of forty.
No comments:
Post a Comment