Advanced Jenkins
Shared Libraries in Jenkins
Demo Refactor existing Jenkinsfile
In this lesson, we’ll walk through refactoring our existing Jenkinsfile to serve as the foundation for more advanced pipeline demos. You’ll learn how to:
- Extract reusable helpers (e.g., Slack notifications)
- Simplify and structure stages for clarity
- Spin up a new feature branch for future enhancements
- Verify the pipeline in both classic and Blue Ocean views
By the end, you’ll have a lean, maintainable Jenkins pipeline ready for advanced integrations.
Recap: Jenkins Multibranch Pipeline
Log in to your Jenkins instance and find the multibranch Organization Folder containing the solar-system repository. This setup automatically discovers and builds branches as they appear in your Git server.
Within solar-system, our last active branch was feature/enabling-slack
.
On the Git side, the project lives under the dasher-org organization in Gitea alongside related repositories.
We pushed our last updates to the feature/enabling-slack
branch.
Step 1: Open the Jenkinsfile in VS Code
Switch your local repo to feature/enabling-slack
and open Jenkinsfile in Visual Studio Code (or your preferred editor).
Prerequisites
Ensure you have the following installed on your Jenkins agents:
- Node.js & npm
- Docker Engine
- Trivy scanner
- Slack Notification Plugin
Step 2: Extract Slack Notification Helper
To avoid repeating slackSend
calls and status logic, define a reusable helper function at the top of your Jenkinsfile:
// Slack Notification helper
def slackNotificationMethod(String buildStatus = 'STARTED') {
buildStatus = buildStatus ?: 'SUCCESS'
def color = (buildStatus == 'SUCCESS') ? '#47ec05' :
(buildStatus == 'UNSTABLE') ? '#d5eed0' : '#ec2805'
def msg = "${buildStatus}: ${env.JOB_NAME} #${env.BUILD_NUMBER}:\n${env.BUILD_URL}"
slackSend(color: color, message: msg)
}
This helper centralizes notification logic and can be invoked in any post
block.
Step 3: Simplify Pipeline Structure
We’re focusing on five key stages for our advanced demos. Comment out or remove any extra stages. The new skeleton looks like this:
pipeline {
agent any
options {
timestamps()
skipDefaultCheckout()
}
environment {
MONGO_URI = "mongodb+srv://supercluster.d83jj.mongodb.net/superData"
MONGO_DB_CRED = credentials('mongo-db-credentials')
SONAR_SCANNER_HOME = tool 'sonarqube-scanner-610'
GITEA_TOKEN = credentials('gitea-api-token')
}
stages {
stage('Installing Dependencies') { steps { sh 'npm install --no-audit' } }
stage('Dependency Scanning') {
parallel {
stage('NPM Dependency Audit') { steps { sh 'npm audit --json > audit.json' } }
// OWASP Dependency Check removed for this demo
}
}
stage('Unit Testing') { steps { sh 'npm test' } }
stage('Code Coverage') {
steps {
catchError(buildResult: 'SUCCESS', message: 'Coverage issues', stageResult: 'FAILURE') {
sh 'npm run coverage'
}
}
}
stage('Build Docker Image') { steps { sh 'docker build -t ${env.JOB_NAME}:${env.GIT_COMMIT} .' } }
stage('Trivy Vulnerability Scanner') {
steps {
sh '''
trivy image ${env.JOB_NAME}:${env.GIT_COMMIT} \
--severity LOW,MEDIUM,HIGH --exit-code 0 --format json \
-o trivy-image-MEDIUM-results.json
trivy convert --format template \
--template "/usr/local/share/trivy/templates/html.tpl" \
--output trivy-image-MEDIUM-results.html \
trivy-image-MEDIUM-results.json
trivy convert --format template \
--template "/usr/local/share/trivy/templates/junit.tpl" \
--output trivy-image-CRITICAL-results.xml \
trivy-image-MEDIUM-results.json
'''
}
post {
always {
publishHTML(
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: './',
reportFiles: 'trivy-image-MEDIUM-results.html',
reportName: 'Trivy HTML Report'
)
publishHTML(
allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: './',
reportFiles: 'trivy-image-CRITICAL-results.xml',
reportName: 'Trivy JUnit Report'
)
}
}
}
}
post {
always {
slackNotificationMethod(currentBuild.currentResult)
script {
if (fileExists('solar-system-gitops-argocd')) {
sh 'rm -rf solar-system-gitops-argocd'
}
}
junit allowEmptyResults: true, testResults: 'test-results.xml'
junit allowEmptyResults: true, testResults: 'dependency-check-junit.xml'
publishHTML(
allowMissing: true,
alwaysLinkToLastBuild: true,
reportDir: 'coverage/',
reportFiles: 'lcov.info',
reportName: 'Coverage Report'
)
}
}
}
Key Pipeline Stages Summary
Stage | Purpose |
---|---|
Installing Dependencies | Install npm modules without audit |
Dependency Scanning | Run npm audit in parallel |
Unit Testing | Execute unit tests |
Code Coverage | Generate coverage report (non-blocking) |
Build Docker Image | Build container for deployment/testing |
Trivy Vulnerability Scanner | Scan image, export HTML & JUnit reports |
Step 4: Create a New Branch for Advanced Demos
Instead of modifying feature/enabling-slack
, spin up a fresh feature branch:
git checkout -b feature/advanced-demo origin/feature/enabling-slack
git push -u origin feature/advanced-demo
Jenkins Multibranch Pipeline will auto-detect and trigger a build for the new branch.
Step 5: Verify in Blue Ocean
Open the Blue Ocean UI to get a visual representation of your streamlined pipeline. You should now see only the core stages instead of the full, unfiltered list.
With your Jenkinsfile refactored and a dedicated branch in place, you’re all set to explore advanced pipeline features in upcoming sessions.
Links and References
- Jenkins Pipeline Syntax
- Slack Notification Plugin
- Trivy: A Simple and Comprehensive Vulnerability Scanner
- Blue Ocean Plugin
Watch Video
Watch video content