Ravindra BagaleCourses & study guides मराठी

Chapter 21: Jenkins Pipeline and Jenkinsfile

21.5 Full Declarative Jenkinsfile for badge Node

Why: the problem

Now we write the full Jenkinsfile for the badge Node app. Think of Myntra before a big sale. Every change to the shop app must pass the same checks, in the same order, every time. Checkout the code. Install. Build. Test. Copy the result to a place where people can try it. Keep the build output safe. Tell the team if it broke. If a human does this by hand, one step gets skipped on a busy day. A full Jenkinsfile never skips. It also stops at the first red stage, so a broken build never reaches the live folder. In this lesson you will build the file in three rounds. First the simple stages. Then options and environment. Then post actions, archive and test reports. Each round runs green before the next.

What we will build

You will write the complete badge Node Jenkinsfile with Checkout, Install, Build, Test and Lab Live stages. You will add timestamps, a timeout, an environment block, JUnit test reports, archived artifacts and post messages. You will run it green, break a test, and see the Live stage skipped.

What: every term in plain English

  • checkout scm — Clones the exact commit this build is for.
  • options — Settings for the whole pipeline, like timeout and timestamps.
  • environment — Variables for every stage.
  • archiveArtifacts — Saves files on the build page for download.
  • junit — Reads test result XML and shows a test trend chart.
  • post — Actions after the stages: always, success, failure, unstable, cleanup.
  • Lab Live — A folder on the agent that acts as our practice live server.
  • Skipped stage — A stage that did not run because an earlier one failed.
Add a JUnit reporter Tell Jest to write XML Write the Jenkinsfile Push Run Open the reports Break and watch
Checkout, Install, Build, Test, Live, then post

How: step by step

  1. Add a JUnit reporter

    npm install --save-dev jest-junit
    

    What it does: Lets Jest write test results as XML.

    Output

    added 6 packages in 2s
    
  2. Tell Jest to write XML

    npm pkg set scripts.test="jest --ci --reporters=default --reporters=jest-junit"
    

    What it does: Writes junit.xml on every test run.

    Output

    (no output)
    
  3. Write the Jenkinsfile

    nano Jenkinsfile
    

    What it does: Full file from example 2 below.

    Output

    (file saved)
    
  4. Push

    git add . && git commit -m "ci: full pipeline" && git push
    

    What it does: Jenkins sees the new file.

    Output

    [main 7d3e2a1] ci: full pipeline
    
  5. Run

    Build Now
    

    What it does: All five stages run.

    Output

    Finished: SUCCESS
    
  6. Open the reports

    Build page > Test Result and Build Artifacts
    

    What it does: Shows 2 tests passed and dist/index.html.

    Output

    Test Result (no failures)
    dist/index.html 31 B
    
  7. Break and watch

    Change one expect, push, build
    

    What it does: Test is red, Live is skipped.

    Output

    Stage "Live" skipped due to earlier failure(s)
    

Example 1: Round 1: the five stages

Stack. Jenkins Declarative, Node.js 20

Goal. Round 1: the five stages.

Jenkinsfile

pipeline {
  agent any
  stages {
    stage('Checkout') { steps { checkout scm } }
    stage('Install')  { steps { sh 'npm ci' } }
    stage('Build')    { steps { sh 'npm run build' } }
    stage('Test')     { steps { sh 'npm test' } }
    stage('Live') {
      steps {
        sh 'mkdir -p "$HOME/lab-live/badge-node"'
        sh 'cp -r dist/* "$HOME/lab-live/badge-node/"'
        sh 'ls -l "$HOME/lab-live/badge-node"'
      }
    }
  }
}

What each line does

  • checkout scm — Clones the commit. Declarative does this anyway; writing it makes it visible.
  • mkdir -p — Makes the live folder if missing, no error if it exists.
  • "$HOME/..." — Single quotes in Groovy, so the shell expands HOME, not Groovy.
  • cp -r dist/* — Copies the build to the lab live folder.

Green output

[Pipeline] stage (Checkout)
[Pipeline] stage (Install)
added 276 packages in 8s
[Pipeline] stage (Build)
build done: dist/index.html
[Pipeline] stage (Test)
Tests: 2 passed, 2 total
[Pipeline] stage (Live)
+ ls -l /var/jenkins_home/lab-live/badge-node
-rw-r--r-- 1 jenkins jenkins 31 Oct 25 10:30 index.html
Finished: SUCCESS

Expected result. Five green boxes. The live folder has the new file.

Example 2: Round 2 and 3: the full file

Stack. Jenkins, Jest, jest-junit, Workspace Cleanup plugin

Goal. Round 2 and 3: the full file.

Jenkinsfile

pipeline {
  agent any
  options {
    timestamps()
    timeout(time: 15, unit: 'MINUTES')
    buildDiscarder(logRotator(numToKeepStr: '20'))
    disableConcurrentBuilds()
  }
  environment {
    APP = 'badge-node'
    LIVE_DIR = "${env.HOME}/lab-live/badge-node"
    CI = 'true'
  }
  stages {
    stage('Checkout') { steps { checkout scm } }
    stage('Install')  { steps { sh 'node --version && npm ci' } }
    stage('Build')    { steps { sh 'npm run build' } }
    stage('Test') {
      steps { sh 'npm test' }
      post { always { junit 'junit.xml' } }
    }
    stage('Live') {
      steps {
        sh 'mkdir -p "$LIVE_DIR" && cp -r dist/* "$LIVE_DIR/"'
        echo "Lab live updated for ${APP} build ${BUILD_NUMBER}"
      }
    }
  }
  post {
    success { archiveArtifacts artifacts: 'dist/**', fingerprint: true }
    failure { echo "FAILED: ${APP} #${BUILD_NUMBER} see ${BUILD_URL}console" }
    always  { echo "Result: ${currentBuild.currentResult} in ${currentBuild.durationString}" }
    cleanup { cleanWs() }
  }
}

What each line does

  • timestamps() — Time on every log line.
  • timeout(time: 15, unit: 'MINUTES') — Kills a stuck build after 15 minutes.
  • buildDiscarder — Keeps only the last 20 builds, saves disk.
  • disableConcurrentBuilds() — One build of this job at a time.
  • environment APP, LIVE_DIR, CI — Variables for all stages. CI=true makes tools act non interactive.
  • junit 'junit.xml' — Shows test results, inside a stage post always so it runs even when tests fail.
  • fingerprint: true — Tracks this file across jobs.
  • cleanup { cleanWs() } — Deletes the workspace at the very end. Needs the Workspace Cleanup plugin.

Green output

10:41:02  [Pipeline] stage (Install)
10:41:02  + node --version
10:41:02  v20.15.1
10:41:10  added 276 packages in 8s
10:41:11  [Pipeline] stage (Test)
10:41:14  Tests: 2 passed, 2 total
10:41:14  Recording test results
10:41:15  [Pipeline] stage (Live)
10:41:15  Lab live updated for badge-node build 5
10:41:15  Archiving artifacts
10:41:15  Result: SUCCESS in 14 sec
10:41:16  [WS-CLEANUP] Deleting project workspace...
Finished: SUCCESS

Expected result. A real company shape: time limits, history limits, test reports, artifacts and clean workspace.

Example 3: Break a test and read the red build

Stack. Jenkins Declarative

Goal. Break a test and read the red build.

terminal

sed -i 's/passing/oops/' test/badge.test.js
git commit -am "test: break on purpose"
git push

What each line does

  • sed -i — Makes one test fail.
  • git commit -am — Commits changed tracked files.
  • Live skipped — Declarative skips later stages after a failure.
  • junit still runs — Because it is in post always of the Test stage.

Green output

[Pipeline] stage (Test)
FAIL test/badge.test.js
  x makes a badge
Tests: 1 failed, 1 passed, 2 total
script returned exit code 1
Recording test results
[Pipeline] stage (Live)
Stage "Live" skipped due to earlier failure(s)
FAILED: badge-node #6 see http://localhost:8080/job/badge-scm/6/console
Result: FAILURE in 9.2 sec
Finished: FAILURE

Expected result. The broken code never reached the live folder. The test chart shows one failure. Revert with git revert HEAD.

Verify: did it work?

  1. Check the live folder

    docker exec jenkins ls -l /var/jenkins_home/lab-live/badge-node
    

    What it does: Only green builds update it.

    Output

    index.html
    
  2. Test trend

    Job page > Test Result Trend
    

    What it does: A chart of pass and fail over builds.

    Output

    Chart shows build 6 red
    

When it is red 1

No test report files were found. Configuration error?

Cause. junit.xml was not written, or the path is wrong.

Fix, step by step

  1. Check the test script uses jest-junit.
  2. Run ls in the Test stage.

When it is red 2

No such DSL method 'cleanWs' found among steps

Cause. The Workspace Cleanup plugin is missing.

Fix, step by step

  1. Install Workspace Cleanup.
  2. Or use deleteDir().

When it is red 3

Timeout has been exceeded
Cancelling nested steps due to timeout

Cause. A step hung, like npm waiting for input.

Fix, step by step

  1. Set CI=true.
  2. Find the slow step with timestamps.

When it is red 4

cp: cannot stat dist/*: No such file or directory

Cause. Build did not create dist.

Fix, step by step

  1. Check the build script.
  2. Add ls -l dist after build.

Cleanup

  1. Clear the lab live folder

    docker exec jenkins rm -rf /var/jenkins_home/lab-live/badge-node
    

    What it does: Removes the practice live copy.

    Output

    (no output)
    
  2. Revert the broken test

    git revert --no-edit HEAD && git push
    

    What it does: Back to green.

    Output

    [main 8e1f0b2] Revert "test: break on purpose"
    

Ravindra Bagale's Tip

Test fail zala tar Live skip hoto, he changla aahe. junit post always madhe theva. Lakshat theva!

Practice tasks

Easy Write round 1

Why: Start simple.

What to do: Five stages only.

How:
  1. Run green.

Check: Five green boxes.

Medium Add options and reports

Why: Real jobs need limits and reports.

What to do: Add timeout, junit and archive.

How:
  1. jest-junit.

Check: Test Result page shows.

Hard Fail safely

Why: Live must stay safe.

What to do: Break a test and prove Live is skipped.

How:
  1. Check the live folder.

Check: Old file still there.

Easy Say the full badge 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 the full badge 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, write the full Jenkinsfile, add jest-junit, run it green, then break a test and screenshot the skipped Live stage and the test chart.

Recap

  • Build the Jenkinsfile in rounds.
  • Use options for timeout, timestamps and history.
  • Put junit in post always.
  • Archive artifacts only on success.
  • A failed stage skips the rest.

FAQ

Why junit in the stage post and not the pipeline post?

It runs right after tests even if they fail, and keeps the report next to the stage.

Do I need checkout scm in Declarative?

No, but writing it is clear. Use skipDefaultCheckout to control it.

Why disableConcurrentBuilds?

Two builds writing to the same live folder can mix files.

What does fingerprint do?

It lets you see which jobs used the same file.

Is the lab live folder a real deploy?

No. Real deploys go to servers with SSH, Docker or Kubernetes in later chapters.

Interview questions

  1. Walk me through your Jenkinsfile.

    Checkout, install, build, test with junit, deploy step, post actions for archive, notify and cleanup, with timeout and history options.

  2. How do you show tests in Jenkins?

    Write JUnit XML and call junit in post always.

  3. How do you stop a hung build?

    timeout in options or around a step.

  4. How do you save build output?

    archiveArtifacts with fingerprint in post success.

  5. What happens after a failed stage?

    Later stages are skipped and post failure and always run.

Quick quiz

Q1. Which option stops a stuck build?

timeout.

Q2. Where should junit go?

In post always of the Test stage.

Q3. What happens to Live when Test fails?

It is skipped.

Q4. Which post block runs last?

cleanup.

Q5. What does buildDiscarder do?

Deletes old builds.

Samajla ka?

Ravi Sir's Cards for this lesson

मराठी cards