Ravindra BagaleCourses & study guides मराठी

Chapter 21: Jenkins Pipeline and Jenkinsfile

21.1 Why move Freestyle into a Jenkinsfile

Why: the problem

Think of Zomato. Their team has a Freestyle Jenkins job for the order service. It has twelve text boxes, three build steps and a post-build email. One day someone changes the Node version in a text box. The build breaks. Nobody knows who changed it, or what it was before. There is no review and no history. Now think of 80 such jobs. This is the Freestyle problem. The job lives only inside Jenkins, as clicks. A Jenkinsfile fixes it. A Jenkinsfile is a plain text file in the same Git repo as the app. It describes the build as code. Every change goes through a pull request. Git shows who changed what and when. If Jenkins dies, you create one job that points to the repo, and the whole build comes back. In this lesson you will take a real Freestyle job, read its settings, and write the same thing as a Jenkinsfile, step by step.

What we will build

You will start a lab Jenkins in Docker. You will create a Freestyle job for the badge Node app, run it, and note every field. Then you will write a Jenkinsfile with the same steps, commit it, and run it as a Pipeline job. At the end you will compare both console logs line by line.

What: every term in plain English

  • Freestyle job — The old Jenkins job type. You fill text boxes and pick build steps with the mouse.
  • Pipeline job — A job that runs a script written in Groovy, called a pipeline.
  • Jenkinsfile — A text file named Jenkinsfile in the root of the Git repo. It holds the pipeline.
  • Pipeline as code — The build steps live in Git, next to the app code, and are reviewed like code.
  • Stage — A named block of work, like Build or Test. Each stage shows as a box on the build page.
  • Step — One action inside a stage, like sh, echo or archiveArtifacts.
  • config.xml — The file where Jenkins stores a Freestyle job. Hard to read, not in Git.
  • Groovy — The language Jenkins pipelines are written in. You need only a small part of it.
Start a lab Jenkins Install the Pipeline plugins Look at the Freestyle config Write the Jenkinsfile Commit and push Create the Pipeline job Run and compare
Freestyle clicks to a Jenkinsfile in Git

How: step by step

  1. Start a lab Jenkins

    docker volume create jenkins_home
    docker run -d --name jenkins -p 8080:8080 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17
    

    What it does: Runs Jenkins LTS with data kept in a named volume.

    Output

    jenkins_home
    7c1e0f2a9b... (container ID)
    
  2. Install the Pipeline plugins

    Manage Jenkins > Plugins > Available > Pipeline, Git, Timestamper > Install
    

    What it does: Pipeline is the engine. Git lets Jenkins clone repos.

    Output

    Pipeline: Success
    Git: Success
    Timestamper: Success
    
  3. Look at the Freestyle config

    docker exec jenkins cat /var/jenkins_home/jobs/badge-freestyle/config.xml | head -20
    

    What it does: Shows how Jenkins stores the clicks as XML.

    Output

    ?xml version=1.1 encoding=UTF-8?
    project
      builders
        hudson.tasks.Shell
          command npm ci ...
    
  4. Write the Jenkinsfile

    cd badge-node
    nano Jenkinsfile
    

    What it does: Creates the file in the repo root, with the same steps as the Freestyle job.

    Output

    (file saved)
    
  5. Commit and push

    git add Jenkinsfile
    git commit -m "ci: move build into Jenkinsfile"
    git push origin main
    

    What it does: The build is now in Git with an author and date.

    Output

    [main 4b2d9e1] ci: move build into Jenkinsfile
     1 file changed, 24 insertions(+)
    
  6. Create the Pipeline job

    New Item > badge-pipeline > Pipeline > Definition: Pipeline script from SCM > Git > repo URL > Script Path: Jenkinsfile
    

    What it does: Jenkins reads the build from Git on every run.

    Output

    Saved
    
  7. Run and compare

    Build Now > Console Output
    

    What it does: Both jobs print the same npm lines. The Pipeline job also shows stage boxes.

    Output

    Finished: SUCCESS
    

Example 1: The Freestyle job, written down as text first

Stack. Jenkins LTS, Freestyle job

Goal. The Freestyle job, written down as text first.

freestyle-notes.txt

Job name     : badge-freestyle
SCM          : Git, branch */main
Build step 1 : Execute shell -> npm ci
Build step 2 : Execute shell -> npm run build
Build step 3 : Execute shell -> npm test
Post-build   : Archive the artifacts -> dist/**
Trigger      : Poll SCM H/5 * * * *

What each line does

  • Job name — The name you typed on New Item.
  • SCM — Where the code comes from and which branch.
  • Build step 1-3 — Each Execute shell box becomes one sh step later.
  • Post-build — Archive the artifacts becomes archiveArtifacts.
  • Trigger — Poll SCM becomes a triggers block (lesson 21.16).

Green output

Started by user admin
Cloning repository https://git.example.com/team/badge-node.git
+ npm ci
added 212 packages in 7s
+ npm run build
build done: dist/index.html
+ npm test
Tests: 9 passed, 9 total
Archiving artifacts
Finished: SUCCESS

Expected result. Writing the clicks as plain notes first makes the move to code easy. Each line maps to one part of the Jenkinsfile.

Example 2: The same job as a Jenkinsfile

Stack. Jenkins Pipeline from SCM

Goal. The same job as a Jenkinsfile.

Jenkinsfile

pipeline {
  agent any
  stages {
    stage('Install') {
      steps { sh 'npm ci' }
    }
    stage('Build') {
      steps { sh 'npm run build' }
    }
    stage('Test') {
      steps { sh 'npm test' }
    }
  }
  post {
    success {
      archiveArtifacts artifacts: 'dist/**'
    }
  }
}

What each line does

  • pipeline { — The start of a Declarative pipeline. Everything goes inside.
  • agent any — Run on any free executor.
  • stages { — The list of stages, in order, top to bottom.
  • stage('Install') — A box named Install on the build page.
  • sh 'npm ci' — Runs a shell command, same as Execute shell.
  • post { success { — Runs only when all stages passed.
  • archiveArtifacts artifacts: 'dist/**' — Saves the dist folder on the build page.

Green output

Obtained Jenkinsfile from git https://git.example.com/team/badge-node.git
[Pipeline] stage (Install)
+ npm ci
added 212 packages in 6s
[Pipeline] stage (Build)
+ npm run build
build done: dist/index.html
[Pipeline] stage (Test)
+ npm test
Tests: 9 passed, 9 total
[Pipeline] archiveArtifacts
Archiving artifacts
Finished: SUCCESS

Expected result. Same commands, same result. Now the build is in Git and shows three green stage boxes.

Example 3: Prove the history works: change Node flags through Git

Stack. Git, Jenkins Pipeline

Goal. Prove the history works: change Node flags through Git.

Jenkinsfile (changed)

pipeline {
  agent any
  environment {
    NODE_OPTIONS = '--max-old-space-size=1024'
  }
  stages {
    stage('Install') { steps { sh 'npm ci' } }
    stage('Build')   { steps { sh 'npm run build' } }
    stage('Test')    { steps { sh 'npm test' } }
  }
}

terminal

git add Jenkinsfile
git commit -m "ci: give node 1 GB heap for build"
git push origin main
git log --oneline -3 -- Jenkinsfile

What each line does

  • environment { — Sets variables for every stage.
  • NODE_OPTIONS — A Node setting. Here it gives the build more memory.
  • git log -- Jenkinsfile — Shows only commits that touched the Jenkinsfile.
  • Pull request — In a real team this change goes through review before main.

Green output

9a0c3f2 ci: give node 1 GB heap for build
4b2d9e1 ci: move build into Jenkinsfile
1f7e8a0 first commit

Expected result. Every build change now has an author, a date and a message. Rollback is git revert.

Verify: did it work?

  1. Replay the build

    Build page > Replay
    

    What it does: Lets you edit the Jenkinsfile for one test run without a commit.

    Output

    Replayed #3
    
  2. See the stages

    Build page > Pipeline Overview (or Stage View)
    

    What it does: Shows each stage as a box with its time.

    Output

    Install 6s | Build 3s | Test 4s
    

When it is red 1

ERROR: Unable to find Jenkinsfile from git https://git.example.com/team/badge-node.git

Cause. The file is missing, in a sub folder, or named jenkinsfile in small letters.

Fix, step by step

  1. Run git ls-files and check the exact name.
  2. Put it in the repo root or set Script Path.
  3. Push again and rebuild.

When it is red 2

No such DSL method 'pipeline' found among steps

Cause. The Pipeline plugins are not installed.

Fix, step by step

  1. Install the Pipeline plugin set.
  2. Restart Jenkins.
  3. Run the job again.

When it is red 3

WorkflowScript: 3: Expected a stage @ line 3, column 5.

Cause. A bracket is missing or a stage is outside stages.

Fix, step by step

  1. Count opening and closing braces.
  2. Use the Pipeline Syntax page or the linter in lesson 21.10.

Cleanup

  1. Delete the old Freestyle job

    badge-freestyle > Delete Project
    

    What it does: Removes the click job once the Pipeline job is green for a week.

    Output

    Project deleted
    
  2. Remove the lab

    docker rm -f jenkins && docker volume rm jenkins_home
    

    What it does: Deletes the lab controller and its data.

    Output

    jenkins
    jenkins_home
    

Ravindra Bagale's Tip

Freestyle madhe history nahi. Jenkinsfile Git madhe theva, mag kon kay badalla te disel. Lakshat theva!

Practice tasks

Easy List your Freestyle fields

Why: You cannot move what you have not written down.

What to do: Write every field of one Freestyle job as text.

How:
  1. Open Configure.
  2. Copy each field.

Check: Your notes match the job.

Medium Convert one job

Why: Practice the mapping.

What to do: Turn the notes into a Jenkinsfile with 3 stages.

How:
  1. One stage per build step.
  2. post for archive.

Check: Pipeline job is green.

Hard Delete the Freestyle job

Why: Two copies drift apart.

What to do: Run the Pipeline job for a week, then delete the Freestyle job.

How:
  1. Compare results daily.

Check: Only the Pipeline job remains.

Easy Say moving Freestyle to a Jenkinsfile in two lines

Why: If you can say it simply, you understand it. Juniors and interviewers want the short version first.

What to do: Write two short lines about moving Freestyle to a Jenkinsfile for a fresher who knows only Linux basics.

How:
  1. Write what problem it solves.
  2. Write the one command or menu you use for it.
  3. Read it aloud to a friend.

Check: A fresher understands it without asking a question.

Easy Start a fresh lab Jenkins

Why: Practice needs a throwaway Jenkins. If you break it, you delete it and start again.

What to do: Run Jenkins LTS in Docker with a named volume.

How:
  1. docker volume create jenkins_home
  2. docker run -d --name jenkins -p 8080:8080 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17
  3. docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Check: The Jenkins unlock page opens on localhost:8080.

Medium Break it on purpose

Why: You must know the red message by face. During an outage there is no time to read slowly.

What to do: Cause one error from the "When it is red" part of this lesson and fix it.

How:
  1. Follow the error section.
  2. Copy the exact message into your notes.
  3. Write the fix in one line.

Check: You fixed it using only the steps, without searching the web.

Medium Write a one-page runbook

Why: At 2 a.m. nobody remembers where a file lives. A short page saves the on-call person.

What to do: Write a runbook page for this lesson.

How:
  1. Title, when to use, exact command, how to check, how to undo.

Check: A teammate can follow it alone.

Medium Repeat it on a cloud VM

Why: A laptop is not a server. Real Jenkins runs on EC2 or a company VM.

What to do: Do the main steps of this lesson again on a small Ubuntu 22.04 EC2 instance.

How:
  1. Launch t3.small with 20 GB disk.
  2. Open port 22 only to your IP.
  3. Repeat the steps and compare the output.

Check: Same green output on the VM as on your laptop.

Hard Explain it like an interview

Why: Interviewers want real stories, not definitions.

What to do: Record a 60 second answer about this lesson.

How:
  1. Say the problem, the command you ran, and one error you hit.

Check: Your answer has a real command and a real error message.

Hard Draw the flow top to bottom

Why: A drawing shows who talks to whom and in what order.

What to do: Draw this lesson as boxes from top to bottom.

How:
  1. Start at the developer push, go through the controller and agent, end at the result.

Check: Each box matches a real thing you saw on screen.

Homework: try at home

Try at home

At home, pick any Freestyle job you have. Write its fields as notes, then write the Jenkinsfile, push it and run it as a Pipeline job. Take a screenshot of both console logs side by side.

Recap

  • Freestyle jobs are clicks with no history.
  • A Jenkinsfile is the build as code in Git.
  • Each Execute shell becomes one sh step.
  • post success replaces post-build actions.
  • Changes go through Git review and can be reverted.

FAQ

Do I need to learn all of Groovy?

No. Declarative pipeline uses a small, fixed shape. You learn the blocks, not the language.

Can a Jenkinsfile have another name?

Yes. Set Script Path, like ci/Jenkinsfile.build. Keep the default when you can.

Is Freestyle removed from Jenkins?

No, it still works. Teams move away because of review and history.

Can I keep secrets in the Jenkinsfile?

Never. Keep secrets in Jenkins credentials and use the id only.

What if Jenkins is lost?

Create one Pipeline job pointing to the repo. The build comes back from Git.

Interview questions

  1. Why move from Freestyle to Jenkinsfile?

    Pipeline as code gives review, history, rollback and easy rebuild of Jenkins. Freestyle settings live only in config.xml on the controller.

  2. Where does Jenkins read the Jenkinsfile from?

    From the Git repo of the job, at the branch being built, using Pipeline script from SCM.

  3. How do you map a Freestyle shell step?

    Each Execute shell box becomes an sh step inside a stage.

  4. How do you test a Jenkinsfile change quickly?

    Use Replay on a past build, then commit the working version.

  5. A job says Unable to find Jenkinsfile. What do you check?

    The file name, its path, the branch, and the Script Path setting.

Quick quiz

Q1. Where does a Jenkinsfile live?

In the root of the app Git repo.

Q2. Which step replaces Execute shell?

sh.

Q3. What runs only when all stages passed?

post { success { } }.

Q4. Why is pipeline as code better?

It is reviewed, versioned and easy to restore.

Q5. Which button tests a change without a commit?

Replay.

Samajla ka?

Ravi Sir's Cards for this lesson

मराठी cards