Operations 7 min read

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.

DevOps Cloud Academy
DevOps Cloud Academy
DevOps Cloud Academy
Migrating Jenkins Freestyle Jobs to Pipeline: A Step‑by‑Step Guide

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.

CI/CDAutomationdevopsJenkinsFreestyle
DevOps Cloud Academy
Written by

DevOps Cloud Academy

Exploring industry DevOps practices and technical expertise.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.