DEV Community

Cover image for I Was Scared of Jenkins. Then I Built a Full CI/CD Pipeline From One git push
Vivian Chiamaka Okose
Vivian Chiamaka Okose

Posted on Originally published at vivianokose.hashnode.dev

I Was Scared of Jenkins. Then I Built a Full CI/CD Pipeline From One git push

I watched an entire Jenkins video series and understood almost none of it. The moment
Groovy appeared, I zoned out, convinced I needed to learn a programming language to do this
job. I was wrong, and figuring out why unlocked everything.

By the end I had a pipeline that, from one git push, computes the version, lints, tests,
builds a Docker image, pushes it to a registry, deploys it, verifies it, and tags the
release. Automatically.

The fear-buster

A Jenkinsfile is a fill-in-the-blanks form, not a language. The structure
pipeline { stages { stage { steps { } } } } is fixed. You fill in stage names and shell
commands you already know. That is it.

Two servers

A Jenkins server (the factory, runs the pipeline) and an app server (the shop, runs the
app). Jenkins builds and ships; it never runs the app.

Jenkins dashboard
Jenkins on its own server.

Secrets in a vault

Every secret (SSH key, server IP, Docker Hub token, GitHub token) lives in Jenkins'
credential store with a label. The Jenkinsfile references the label, never the secret.

Credentials
Secrets referenced by label.

Eight stages

Checkout, Compute Version, Lint, Test, Build and Push, Deploy, Verify, Tag Release. Runs
top to bottom, stops on any failure so broken code never deploys.

All green
A full run, every stage green.

The webhook makes it automatic

A doorbell: GitHub pings Jenkins on every push, so the pipeline runs on its own. I opened
Jenkins only to GitHub's webhook IP ranges, not the whole internet.

Auto-triggered
A build that started itself after a push.

Multibranch and PR checks

Every branch and pull request builds automatically, and the PR shows a pass/fail check on
GitHub. Deploy runs only on main, so feature branches are tested but never shipped.

PR check
The check stamped on the pull request.

Shared library

The build-and-push logic lives in a separate repo. The Jenkinsfile calls it in one line.
Fix once, every project gets the fix.

Shared library
Calling the shared function.

Dynamic versioning

A feat: commit bumps the minor version, a fix: bumps the patch. The pipeline reads
the commit and tags the release. No human picks a version.

Auto tags
feat produced v0.1.0, fix produced v0.1.1.

The bugs that taught me most

Cloud account suspended mid-build (rebuilt on a new provider, faster the second time).
Deleted my SSH keys with a careless command. Jenkins refusing to start on the wrong Java
version. A stage hanging because my lint command started a never-ending server. A first run
failing on a missing tool. Every one was a real lesson.

Takeaway

Jenkins is a form, not a language. The full code and screenshots:
https://github.com/vivianokose/nexaops-operations-lab/tree/main/08-jenkins

Top comments (0)