Ravindra BagaleCourses & study guides मराठी

Chapter 25: Shared Libraries, Credentials and Environments

25.3 @Library in the app Jenkinsfile

Why: the problem

A Flipkart team gets a new microservice, cart-api. The platform team says: use badge-lib. But how exactly should the new Jenkinsfile load it? Some people write @Library at the top. Some use the library step inside script. Some forget the underscore and get a strange error. Some load main in production and break checkout on a Friday. This lesson is about the app side. You will learn every way to write @Library, how to load a branch for testing, how to load two libraries, how to load a library dynamically, and how to make a folder-level library that only one team can see.

What we will build

You will write the cart-api Jenkinsfile in four ways. First, the simple @Library with the default version. Second, a pinned tag. Third, a feature branch of the library for testing a change before merge. Fourth, the library step that loads at run time. You will also set up a folder-level library for the payments team.

What: every term in plain English

  • @Library annotation — Loads a library before the pipeline starts. Must be the first line.
  • library step — Loads a library during the run, like library('badge-lib@dev'). Good for dynamic versions.
  • Implicit load — Library setting that loads it in every job without @Library. Use with care.
  • Folder library — A library set on a folder. Only jobs in that folder can use it, and it runs in the sandbox.
  • Sandbox — A Groovy safety mode. Unsafe methods need admin approval.
  • Version string — After @, a branch, tag or commit id.
  • Multiple libraries — @Library(['badge-lib', 'pay-lib@v2']) _ loads two at once.
  • Replay — Jenkins feature to edit and rerun a build, including library files, for quick tests.
Simplest form Pinned form Test a library branch Two libraries Dynamic load Folder library Replay a change
Ways an app loads a library, top to bottom

How: step by step

  1. Simplest form

    @Library('badge-lib') _
    

    What it does: Loads the default version set by the admin.

    Output

    Loading library badge-lib@main
    
  2. Pinned form

    @Library('badge-lib@v1.4.0') _
    

    What it does: Loads a tag. Best for production.

    Output

    Loading library badge-lib@v1.4.0
    
  3. Test a library branch

    @Library('badge-lib@feature/new-scan') _
    

    What it does: Try the library change on one app before merging.

    Output

    Loading library badge-lib@feature/new-scan
    
  4. Two libraries

    @Library(['badge-lib@v1.4.0', 'pay-lib@v2.1.0']) _
    

    What it does: Loads both. Steps from both are available.

    Output

    Loading library badge-lib@v1.4.0
    Loading library pay-lib@v2.1.0
    
  5. Dynamic load

    library "badge-lib@${params.LIB_VERSION}"
    

    What it does: Loads the version picked in a parameter.

    Output

    Loading library badge-lib@v1.5.0-rc1
    
  6. Folder library

    Payments folder > Configure > Pipeline Libraries > Add > name pay-lib
    

    What it does: Only jobs inside Payments can load pay-lib.

    Output

    Saved
    
  7. Replay a change

    Build #12 > Replay > edit vars/badgeCi.groovy > Run
    

    What it does: Test a library edit without pushing.

    Output

    Replayed #12
    

Example 1: Write cart-api with a pinned library

Stack. Spring Boot, Maven, Jenkins

Goal. Write cart-api with a pinned library.

cart-api/Jenkinsfile

@Library('badge-lib@v1.4.0') _

badgeCi(
  app: 'cart-api',
  testCmd: 'mvn -B -q test'
)

What each line does

  • @Library('badge-lib@v1.4.0') _ — First line. Loads the tag.
  • app: 'cart-api' — Image name and labels use this.
  • testCmd: 'mvn -B -q test' — cart-api is Java, so it overrides the default npm test.
  • No pipeline block — badgeCi builds the whole pipeline.

Green output

Loading library badge-lib@v1.4.0
Checking out Revision 9c3d7e1 (v1.4.0)
[Pipeline] stage (Test)
+ mvn -B -q test
Tests run: 58, Failures: 0, Errors: 0, Skipped: 0
[Pipeline] stage (Build)
+ docker build -t cart-api:7 .
[Pipeline] stage (Scan)
Total: 0 (HIGH: 0, CRITICAL: 0)
Finished: SUCCESS

Expected result. A Java service uses the same shared pipeline with one change.

Example 2: Use your own pipeline and call small library steps

Stack. Jenkins, two shared libraries

Goal. Use your own pipeline and call small library steps.

cart-api/Jenkinsfile

@Library(['badge-lib@v1.4.0', 'pay-lib@v2.1.0']) _
import com.badge.Version

pipeline {
  agent { label 'docker' }
  stages {
    stage('Version') { steps { script { env.V = new Version(this).next() } } }
    stage('Build')   { steps { sh "docker build -t cart-api:${env.V} ." } }
    stage('PCI check') { steps { payPciCheck(image: "cart-api:${env.V}") } }
    stage('Smoke')   { steps { smokeTest('http://10.0.2.15:8080') } }
  }
}

What each line does

  • Two libraries in a list — badge-lib for common steps, pay-lib for payment rules.
  • import com.badge.Version — Class from badge-lib src.
  • payPciCheck — A step from pay-lib vars.
  • smokeTest — A step from badge-lib vars.
  • Own pipeline — The team keeps control of stage order.

Green output

Loading library badge-lib@v1.4.0
Loading library pay-lib@v2.1.0
[Pipeline] stage (Version)
v1.0.8
[Pipeline] stage (Build)
+ docker build -t cart-api:v1.0.8 .
[Pipeline] stage (PCI check)
PCI: no card data in image layers
[Pipeline] stage (Smoke)
try 1 -> 200
SMOKE OK
Finished: SUCCESS

Expected result. Mixing libraries works. Each team owns its own steps.

Example 3: Pick the library version with a parameter

Stack. Jenkins, parameters, dynamic library

Goal. Pick the library version with a parameter.

cart-api/Jenkinsfile

pipeline {
  agent { label 'docker' }
  parameters {
    string(name: 'LIB_VERSION', defaultValue: 'v1.4.0', description: 'badge-lib tag or branch')
  }
  stages {
    stage('Load') {
      steps {
        script {
          library "badge-lib@${params.LIB_VERSION}"
          sayHello('cart-api')
        }
      }
    }
  }
}

What each line does

  • parameters { string ... } — Adds a text box on Build with Parameters.
  • library "badge-lib@..." — Loads the library while the build runs.
  • script { } — The library step must run inside script in declarative.
  • Use case — Platform team tests v1.5.0-rc1 on real apps without changing their files.

Green output

Loading library badge-lib@v1.5.0-rc1
Namaste cart-api from badge-lib
Finished: SUCCESS

Expected result. You tested a release candidate safely on a real app.

Verify: did it work?

  1. Confirm the loaded commit

    Console Output > search Checking out Revision
    

    What it does: Shows the exact commit used.

    Output

    Checking out Revision 9c3d7e1 (v1.4.0)
    
  2. List folder libraries

    Folder > Configure > Pipeline Libraries
    

    What it does: Shows libraries visible only in that folder.

    Output

    pay-lib  default: v2.1.0
    

When it is red 1

unexpected token: pipeline @ line 2

Cause. The underscore after @Library is missing.

Fix, step by step

  1. Change the first line to end with ) _
  2. Save and run again.

When it is red 2

Library pay-lib not found

Cause. The job is outside the folder that owns pay-lib.

Fix, step by step

  1. Move the job into the Payments folder.
  2. Or ask an admin to make it global.

When it is red 3

Scripts not permitted to use method java.io.File list

Cause. Folder libraries run in the sandbox.

Fix, step by step

  1. Avoid java.io.File; use sh or findFiles.
  2. Or ask an admin to approve in In-process Script Approval if truly needed.

Cleanup

  1. Remove the test parameter

    Delete the parameters block and commit
    

    What it does: Production jobs should pin a tag, not take a free text version.

    Output

    Committed
    

Ravindra Bagale's Tip

@Library pahili line, shevti underscore visru naka. Production la tag pin. Lakshat theva!

Practice tasks

Easy Default load

Why: Start simple.

What to do: Load badge-lib with no version.

How:
  1. Run the job.

Check: Console shows @main.

Medium Branch test

Why: Test library changes before merge.

What to do: Load a feature branch in one app.

How:
  1. Push a branch.
  2. Change @ in the app.

Check: Console shows the branch.

Hard Folder library

Why: Teams need private helpers.

What to do: Make a folder library and prove another folder cannot load it.

How:
  1. Create two folders.

Check: Second folder fails with not found.

Easy Say loading a shared library 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 loading a shared library 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 one Jenkinsfile three ways: default version, pinned tag, and dynamic library step. Run all three and compare the Loading library lines.

Recap

  • @Library goes first, with an underscore.
  • Pin tags in production.
  • Use branches to test library changes.
  • The library step loads at run time.
  • Folder libraries are private and sandboxed.

FAQ

Should every app pin a version?

Production apps yes. Sandbox apps can follow main.

Can I load by commit id?

Yes, @ followed by the commit id.

Is implicit loading good?

Only for tiny global helpers. It hides where steps come from.

Does Replay change Git?

No. It is only for that one run.

Can a library load another library?

Yes, with the library step inside it, but keep it simple.

Interview questions

  1. How does an app Jenkinsfile load a shared library?

    With @Library('name@version') _ at the top, or the library step inside script for dynamic loading.

  2. How do you test a library change safely?

    Push a branch, load it with @branch on one app or use Replay, then merge and tag.

  3. Global vs folder library?

    Global is trusted and visible everywhere. Folder is sandboxed and visible only in that folder.

  4. Why pin library versions?

    So a library change cannot break production builds without review.

  5. What does the underscore do?

    It gives the annotation something to attach to when you import nothing else.

Quick quiz

Q1. Where must @Library be?

At the very top of the Jenkinsfile.

Q2. How do you load two libraries?

A list inside @Library.

Q3. Which form loads at run time?

The library step.

Q4. Who can see a folder library?

Only jobs inside that folder.

Q5. What does Replay let you do?

Edit and rerun a build without pushing.

Samajla ka?

Ravi Sir's Cards for this lesson

मराठी cards