Migrating Jenkins Freestyle Jobs to Pipeline: A Step‑by‑Step Guide
This article explains why and how to replace Jenkins Freestyle projects with Pipeline jobs, detailing the limitations of Freestyle, the benefits of Pipeline, and providing a complete scripted pipeline example that automates code checkout, building, testing, reporting, and email notifications.
Many organizations use Jenkins for continuous integration, testing, and deployment, often starting with Freestyle projects, which have notable limitations such as single‑repository SCM polling and difficulty handling long‑running unit‑test stages. To address these issues, the author migrated all Freestyle jobs to Pipeline projects.
The migration is triggered whenever developers push updates to the repository; one job builds a binary while another runs unit tests to verify code coverage. Because unit‑test coverage can be time‑consuming, separating these tasks into distinct jobs improves efficiency.
Key reasons for converting to Pipeline include the ability to poll multiple repositories, consolidate many build steps into a single declarative script, and gain clearer stage visualization. The article presents a full Jenkinsfile that defines workspace paths, cleans previous builds, checks out multiple repositories, runs builds, executes unit tests, publishes HTML coverage reports, and sends email notifications.
WSPACE = '/var/jenkins/workspace/Directory_Name/'
BRWSPACE = '/var/jenkins/workspace/'
pipeline {
agent {
node {
label 'Node_Name'
customWorkspace "${WSPACE}"
}
}
// Clean the previous directory
stages {
stage('Cleaning up the previous directory') {
steps {
echo 'Deleteing the directory'
sh "rm -rf /var/jenkins/workspace/Directory_Name/* "
}
}
// Checkout code and dependencies
stage('Checking out build repo and its dependencies') {
steps {
dir("${WSPACE}/RepoName") {
git branch: 'master', credentialsId: 'UserName', url: 'https://github.com/path/repo.git'
}
dir("${WSPACE}/dir") {
git branch: 'master', credentialsId: 'UserName', url: 'https://github.com/path/repo1.git'
}
dir("${WSPACE}/dir3") {
git branch: 'master', credentialsId: 'UserName2', url: 'https://github.com/path/repo4.git'
}
}
}
// Build and versioning
stage('Versioning and executing the build') {
steps {
dir("${WSPACE}/repo1") {
script {
sh '''/usr/bin/env
cd /var/jenkins/workspace/
original=`cat patch_info`
MAJOR=`cat patch_info | cut -d "." -f1`
MINOR=`cat patch_info | cut -d "." -f2`
PATCH=`cat patch_info | cut -d "." -f3`
New_Value=`expr $PATCH + 1`
New_Version=$MAJOR.$MINOR.$New_Value
sed -i "s/$original/$New_Version/g" patch_info
echo "$New_Version"
cd /var/jenkins/workspace/path/repo4/
echo "Starting the Unit Testing"
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
make format
make clean build
if make unit-test ; then
cd /var/jenkins/workspace/path/repo1/dir
else
cd /var/jenkins/workspace/path/repo2/dir2
fi
if make unit-test ; then
echo " unit testing completed"
fi
'''
}
}
}
}
// Publish HTML report
stage('Publish HTML Report') {
steps {
dir("/jenkins/workspace/") {
script {
sh '''/usr/bin/env
perl /jenkins/generate_build_meta_data.pl -jr http://gitlab.com:8080 -bNum ${BUILD_NUMBER} -bName ${JOB_NAME} -o /tmp -t /jenkins/template.html
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
cd /var/jenkins/workspace/path/repo1/service/
go tool cover -html=c.out -o coverage.html
cd /var/jenkins/workspace/path/repo2/dir3
go tool cover -html=c.out -o output.html
'''
publishHTML([allowMissing:false, alwaysLinkToLastBuild:false, keepAll:false, reportDir:'/tmp/${JOB_NAME}/${BUILD_NUMBER}', reportFiles:'${JOB_NAME}-${BUILD_NUMBER}-manifest.html', reportName:'Email Output Subject', reportTitles:''])
}
}
}
}
// Send email
stage('Send Email') {
steps {
dir("${WSPACE}/repo4") {
emailext attachmentsPattern: '**/coverage.html,**/dir4.html', body: '${FILE, path="/tmp/${JOB_NAME}/${BUILD_NUMBER}/${JOB_NAME}-${BUILD_NUMBER}-manifest.html"}', subject: 'Unit testing Email Output ${BUILD_NUMBER} Successful', to: '[email protected], [email protected]'
}
}
}
}
}The pipeline’s staged output is visually appealing and makes the build process easier to understand. In conclusion, the choice between Freestyle and Pipeline depends on project requirements, but Pipeline offers greater flexibility and customization for complex CI/CD workflows.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
