Automating Confidence: Setting Up Continuous Integration with GitHub Actions for a Java Project


Hearing about CI/CD (Continuous Integration / Continuous Deployment) at work these days is very common. Sometimes, though, we nod along without fully understanding what it's all about — or why it's valuable.
I’m a big fan of KISS (Keep it Simple Sweety) so in this article, we’ll break it down in a way that’s easy to grasp — and more importantly, we’ll put it into practice with a real-world example using a Spring Boot Java project. By the end, you won’t just know what Continuous Integration is — you’ll have it running in your Java project, backed by GitHub Actions. 💥 I also include a few pro tips to take it even further along <3
🔄 What Is Continuous Integration?
Continuous Integration (CI) is the practice of automatically building and testing your code every time you make a change — whether it’s a push to your branch or a pull request into main
.
✅ CI helps you:
Catch bugs early
Ensure the codebase is always in a working state
Avoid “works on my machine” scenarios
Move fast without breaking things
Instead of relying on manual testing or guessing if things work, CI makes sure every change is validated automatically.
🚀 What About Continuous Deployment?
Continuous Deployment (CD) is the next step: it automatically deploys your app to production (or a staging environment) after a successful CI run.
CD helps you:
Release faster
Eliminate manual deployment errors
Deliver features with confidence
⚠️ In this article, we’ll focus only on the CI part
🔧 Popular CI/CD Tools
When setting up a CI/CD pipeline, there are several tools commonly used across the industry. Some of the most popular include:
GitHub Actions – tightly integrated with GitHub, easy to set up (used in this article)
GitLab CI/CD – powerful CI/CD built into GitLab
Jenkins – highly configurable open-source automation server
CircleCI – known for speed and cloud-based pipelines
Travis CI – once popular with open source, still in use today
Bitbucket Pipelines – Atlassian’s CI/CD solution
In this article, we’ve chosen GitHub Actions because it integrates directly with GitHub repositories and is simple to get started with.
💪 How GitHub Actions Makes CI Easy
GitHub Actions is GitHub’s built-in automation platform. It allows you to define custom workflows that run on every push, pull request, or even on a schedule.
For example, You can create a workflow that:
Installs Java
Builds your app using Maven
Runs the unit and integration tests
All of this will happen automatically every time you push to main
or open a pull request.
💧 Setting Up CI for a Java Project (Step-by-Step)
1. Create a GitHub Actions workflow file
In your project root, create a new file at:
.github/workflows/ci.yml
This will define the steps GitHub will take to build and test your project. Here's a breakdown of the key parts:
2. Define when your workflow runs
on:
push:
branches: [main]
pull_request:
branches: [main]
This means the workflow will run on any push or pull request targeting the main
branch.
3. Set up the job and environment
jobs:
build-and-test:
runs-on: ubuntu-latest
env:
API_SECRET_KEY: ${{ secrets.API_SECRET_KEY }}
USERNAME: ${{ secrets.USERNAME }}
PASSWORD: ${{ secrets.PASSWORD }}
We define a job called build-and-test
that runs on the latest Ubuntu image. We also load secret environment variables that we’ll define later.
4. Add the build steps
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: '21'
cache: maven
- name: Build and run tests
run: mvn clean verify --batch-mode
checkout@v3
: Clones your code into the runnersetup-java@v3
: Installs Java 21mvn clean verify
: Builds your app and runs the tests
5. Push your workflow file
Once committed to the repository, GitHub Actions immediately starts running it on every push or pull request targeting the main
branch.
You can monitor the results by going to your GitHub repository and clicking on the "Actions" tab. There, you'll see your workflow listed (by the name you gave it in ci.yml
), along with its run history, status, and logs for each step. GitHub Actions immediately starts running it on every push or pull request targeting the main
branch.
🔐 Securing Environment Variables with GitHub Secrets
My app uses JWT authentication, so I needed to provide a secret key, username, and password even for tests. Rather than hardcoding them (which is risky), I used GitHub Secrets.
Why use GitHub Secrets?
✅ Prevent leaking sensitive data (tokens, passwords, API keys)
✅ Encrypted by GitHub
✅ Only exposed to the workflow at runtime — meaning they are securely injected during the execution of the workflow and are never visible in the UI, stored in logs, or accessible after the job ends
How to configure them:
Go to your GitHub repository → Settings
Click Secrets and variables → Actions
Add secrets like:
API_SECRET_KEY
USERNAME
PASSWORD
Now in your YAML workflow, you can use them like this:
env:
API_SECRET_KEY: ${{ secrets.API_SECRET_KEY }}
✅ See this in action
Once I updated my workflow and secrets, I opened this PR:
🔗 Set up CI workflow with GitHub Actions, JWT-secured tests, and test config
As soon as I opened the PR, GitHub ran the CI workflow. My tests passed ✅, my secrets were used securely 🔒, and the PR showed a green checkmark — all automatically.
💡 Pro Tip 1: Since GitHub Actions runs directly in your repository, it's a good idea to make workflow changes on a feature or development branch first. Once you're sure everything works, you can open a pull request to
main
. This approach helps you debug more freely and keeps your commit history cleaner.💡 Pro Tip 2: Once your CI is up and running, consider enabling a branch protection rule on your
main
branch. This ensures that only pull requests with passing builds can be merged — a simple way to prevent broken code from reaching production and to keep your main branch clean and stable.
🧩 What Is the GitHub Actions Marketplace?
The GitHub Actions Marketplace is where you can find reusable actions built by the community and GitHub itself.
Some useful actions I used:
actions/checkout@v3
– pulls your code into the workflowactions/setup-java@v3
– installs Javaactions/cache@v4
– caches dependencies to speed up builds
You can also find actions for linting, Docker builds, deployments, notifications, and more. Think of it like a plugin marketplace for automation.
Final Thoughts
CI isn’t just for big teams. Even if you’re working solo (like I am), it’s worth it. It gives you confidence that your app has been validated automatically and that the code you just added didn’t break anything. It helps you move fast, ship more reliably, and maintain a healthy codebase over time.
Now, every time I push to main
or open a PR, I get that little green ✅ — and behind it, the assurance that everything’s working as expected.
🚀 Ready to Try It Yourself?
If you haven’t set up CI for your project yet, this is a great moment to start.
Keep it simple, secure your secrets, and let GitHub Actions help you catch issues early and ship with confidence.
Subscribe to my newsletter
Read articles from Mirna De Jesus Cambero directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Mirna De Jesus Cambero
Mirna De Jesus Cambero
I’m a backend software engineer with over a decade of experience primarily in Java. I started this blog to share what I’ve learned in a simplified, approachable way — and to add value for fellow developers. Though I’m an introvert, I’ve chosen to put myself out there to encourage more women to explore and thrive in tech. I believe that by sharing what we know, we learn twice as much — that’s precisely why I’m here.