What Are Shared Libraries?
Shared Libraries let you define reusable pipeline code in a separate Git repository, then import it into any Jenkinsfile. This avoids duplicating pipeline logic across projects.
Why Shared Libraries?
| Without | With |
|---|---|
| Copy-paste pipeline code | Single source of truth |
| Inconsistent practices | Standardized steps |
| Hard to update | Update once, applies everywhere |
| No code review for pipelines | Library goes through PR review |
Library Structure
shared-library/
├── vars/ # Global pipeline steps
│ ├── buildApp.groovy # Called as buildApp()
│ ├── deployToK8s.groovy # Called as deployToK8s()
│ ├── notifySlack.groovy # Called as notifySlack()
│ └── standardPipeline.groovy
├── src/ # Helper classes
│ └── org/
│ └── nextgen/
│ ├── Docker.groovy
│ └── Kubernetes.groovy
├── resources/ # Non-Groovy files
│ └── templates/
│ └── deployment.yaml
└── Jenkinsfile # Test the library itself
Writing Custom Steps
vars/buildApp.groovy
// Called as: buildApp(language: 'node', version: '20')
def call(Map config = [:]) {
def language = config.language ?: 'node'
def version = config.version ?: '20'
stage('Build') {
switch(language) {
case 'node':
sh "nvm use ${version} && npm ci && npm run build"
break
case 'python':
sh "pip install -r requirements.txt && python setup.py build"
break
case 'java':
sh "mvn clean package -DskipTests"
break
}
}
}vars/deployToK8s.groovy
def call(Map config) {
def namespace = config.namespace ?: 'default'
def image = config.image
def deployment = config.deployment
def timeout = config.timeout ?: 300
stage('Deploy to Kubernetes') {
withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) {
sh """
kubectl set image deployment/${deployment} \
app=${image} \
--namespace=${namespace}
kubectl rollout status deployment/${deployment} \
--namespace=${namespace} \
--timeout=${timeout}s
"""
}
}
}vars/notifySlack.groovy
def call(Map config) {
def status = config.status ?: 'unknown'
def channel = config.channel ?: '#builds'
def color = status == 'success' ? 'good' : 'danger'
def emoji = status == 'success' ? '✅' : '❌'
slackSend(
channel: channel,
color: color,
message: "${emoji} *${env.JOB_NAME}* #${env.BUILD_NUMBER} - ${status}\n${env.BUILD_URL}"
)
}vars/standardPipeline.groovy
// Full pipeline template
def call(Map config) {
pipeline {
agent { docker { image config.buildImage ?: 'node:20' } }
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Install') {
steps { sh config.installCmd ?: 'npm ci' }
}
stage('Test') {
steps { sh config.testCmd ?: 'npm test' }
}
stage('Build') {
steps { sh config.buildCmd ?: 'npm run build' }
}
stage('Deploy') {
when { branch 'main' }
steps {
deployToK8s(
image: "${config.registry}/${config.appName}:${BUILD_NUMBER}",
deployment: config.appName,
namespace: config.namespace ?: 'production'
)
}
}
}
post {
success { notifySlack(status: 'success') }
failure { notifySlack(status: 'failure') }
}
}
}Using the Library
Configure in Jenkins
Manage Jenkins → System → Global Pipeline Libraries:
- Name:
nextgen-shared - Default version:
main - Source: Git →
https://github.com/org/jenkins-shared-library.git
In a Jenkinsfile
@Library('nextgen-shared') _
// Use individual steps
pipeline {
agent any
stages {
stage('Build') {
steps {
buildApp(language: 'node', version: '20')
}
}
stage('Deploy') {
steps {
deployToK8s(
image: 'registry.example.com/my-app:latest',
deployment: 'my-app',
namespace: 'production'
)
}
}
}
post {
success { notifySlack(status: 'success') }
failure { notifySlack(status: 'failure') }
}
}Using the Full Template
// Entire Jenkinsfile in 10 lines
@Library('nextgen-shared') _
standardPipeline(
appName: 'nextgen-api',
buildImage: 'node:20',
registry: 'registry.example.com',
namespace: 'production',
installCmd: 'npm ci',
testCmd: 'npm run test',
buildCmd: 'npm run build'
)Versioning
// Use a specific version/branch/tag
@Library('nextgen-shared@v2.0.0') _
@Library('nextgen-shared@feature-branch') _
// Load dynamically
library identifier: 'nextgen-shared@main',
retriever: modernSCM([
$class: 'GitSCMSource',
remote: 'https://github.com/org/jenkins-shared-library.git'
])Summary
You've learned:
- Shared Library structure (vars, src, resources)
- Writing custom pipeline steps as reusable functions
- Creating full pipeline templates
- Loading and versioning libraries in Jenkinsfiles
- Standardizing CI/CD across teams
Next Steps
Next, we'll explore Jenkins security, RBAC, and multi-branch pipeline strategies.