Command Palette

Search for a command to run...

Hectal
← All projects

Project 4 of 12 · project brief

CI/CD Pipeline with Jenkins

A declarative Jenkins pipeline: checkout → Maven build and tests → quality gate → Docker image → registry, with credentials handled properly.

Intermediate 2 days 4 milestones

The scenario

ShopLite's enterprise customer runs everything on Jenkins and wants their team trained on a modern setup. Your brief: a pipeline-as-code Jenkins setup that builds and tests every branch, publishes images only from main, and never exposes credentials.

Before you start

Stack

Jenkins LTS (Docker)Docker agentsMavenJUnit + JaCoCoSonarQube (optional)Docker registryMultibranch pipeline

Target architecture

Project 4 architecturediagram
Rendering diagram…

Deliverables and requirements

You will hand in

  • Jenkins running in Docker with configuration as code (JCasC) and pinned plugins
  • A multibranch pipeline driven by a Jenkinsfile in the repo
  • Test reports and coverage published per build
  • Images pushed only from main, tagged with version and Git SHA

Functional

  • Every push and PR triggers a build via webhook
  • Failing tests fail the build and report back to the PR
  • Main builds push images to the registry

Non-functional

  • No builds on the controller (0 executors)
  • Credentials only via Jenkins credentials store and withCredentials, masked in logs
  • Pipeline completes in under 10 minutes with Maven dependency caching

Milestones

  1. 1

    Jenkins as code

    Done when: A reproducible Jenkins: Docker image + plugins.txt + JCasC YAML.

    • Custom image FROM jenkins/jenkins:lts-jdk21 with jenkins-plugin-cli --plugin-file plugins.txt
    • jenkins.yaml (JCasC): security realm, 0 controller executors, credentials from env/secrets, a Docker cloud for agents
    • Run with Docker Compose; persist jenkins_home in a volume

    Prove it works

    terminal
    $ curl -s -u admin:$PW localhost:8080/api/json?tree=numExecutors
    ── expected output ──
    {"_class":"hudson.model.Hudson","numExecutors":0}
  2. 2

    The Jenkinsfile

    Done when: Declarative stages for build, test, and reports, running in a Maven container agent.

    • agent { docker { image 'maven:3.9-eclipse-temurin-21'; args '-v m2:/root/.m2' } }
    • Stages: Checkout, Build & Test (mvn -B verify), Reports (junit, recordCoverage)
    • options { timeout(time: 20, unit: 'MINUTES'); disableConcurrentBuilds() }
    Stuck? Hints
    • Use post { always { junit 'target/surefire-reports/*.xml' } } so reports publish even when tests fail.

    Prove it works

    terminal
    $ # Jenkins UI → shoplite-api » main » #12 → Console Output (tail)
    ── expected output ──
    [Pipeline] junit
    Recording test results
    Tests: 148, Failures: 0, Skipped: 2
    Finished: SUCCESS
  3. 3

    Image build, scan, and conditional push

    Done when: A Docker image built and scanned for every build, pushed only from main.

    • Stage Image: build with the Git SHA tag
    • Stage Scan: trivy image --exit-code 1 --severity CRITICAL
    • Stage Push with when { branch 'main' } and withCredentials([usernamePassword(credentialsId: 'registry', ...)])

    Prove it works

    terminal
    $ # feature branch build log
    ── expected output ──
    Stage "Push" skipped due to when conditional
    Finished: SUCCESS
  4. 4

    Multibranch + webhooks + shared library

    Done when: Every branch and PR builds automatically; common steps live in a shared library.

    • Create a Multibranch Pipeline (GitHub Branch Source) with webhook triggers
    • Move the image build/scan/push steps into a shared library vars/dockerImage.groovy
    • Report build status to GitHub PRs

    Prove it works

    terminal
    $ # open a PR with a failing test
    ── expected output ──
    GitHub PR check: continuous-integration/jenkins/pr-merge — Failure (Tests: 1 failed)

Would you run this in production?

  • ☐Controller runs no builds; agents are ephemeral containers
  • ☐Configuration and plugins as code; plugins pinned and updated regularly
  • ☐Credentials scoped, masked, never echoed; least-privilege registry token
  • ☐Build timeouts, concurrency control, and log retention
  • ☐Backups of jenkins_home (or fully reproducible from code)

Stretch goals

  • Add a SonarQube quality gate (waitForQualityGate abortPipeline: true)
  • Run agents on Kubernetes with the Kubernetes plugin
  • Rebuild the same pipeline in GitHub Actions and compare (CI/CD course, phase 2)

Show it off

Résumé bullet

Built a Jenkins multibranch CI/CD pipeline as code (JCasC, shared libraries, ephemeral Docker agents) with test/coverage reporting, Trivy scanning, and gated image publishing from main.

Demo script

  • Open a PR with a failing test and show the red check
  • Show that a feature-branch build skips Push
  • Show the Jenkins config recreated from scratch in minutes

Interview questions about this project

01

Why shouldn't builds run on the Jenkins controller?

02

Declarative vs scripted pipelines?