We've all been there. You write code, it runs perfectly on your laptop, you push it, and... the build breaks for everyone else. Or worse, a bug sneaks into production because someone forgot to run the tests.
This is where Continuous Integration (CI) comes in.
In this guide, we are going to break down a very simple GitHub Actions workflow that automatically builds and tests 2 Microservices application (Order Service & Product Service) every time you push code.
What Problem Does This Solve?
Before we look at the code, let's understand why we need it. This YAML file lives in your repository. It solves three massive problems:
Consistency: It builds your code in a clean, neutral environment (Ubuntu), not on your potentially messy laptop.
Early Bug Detection: It runs your tests automatically on every Pull Request. You can't merge broken code.
Monorepo Support: It handles multiple services (OrderService and ProductService) in a single repository, ensuring a change in one doesn't break the other.
The Workflow File
Here is the complete ci.yml file we will be analyzing:
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build and Test Order Service
working-directory: ./OrderService
run: |
chmod +x mvnw
./mvnw clean verify
- name: Build and Test Product Service
working-directory: ./ProductService
run: |
chmod +x mvnw
./mvnw clean verify
The Code Breakdown
Let's dissect the configuration line by line.
1.The Setup & Triggers
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
name: This is how the workflow appears in the "Actions" tab on GitHub.
on: These are the triggers. When does this robot wake up?
push: Runs whenever code is pushed to the main branch.
pull_request: Runs whenever someone tries to merge code into main (Crucial for code review!).
workflow_dispatch: A feature that lets you manually click a "Run Workflow" button in the GitHub UI (great for debugging).
2.The Environment (The Job)
jobs:
build:
runs-on: ubuntu-latest
jobs: A workflow is made of one or more jobs. Here, we just have one called build.
runs-on: ubuntu-latest: This tells GitHub to provision a fresh virtual machine running the latest version of Ubuntu Linux. This is where your code will be downloaded and tested.
3.The Steps (The Actual Work)
Step A: Get the Code
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: This keyword pulls in a pre-made script from the GitHub Marketplace. actions/checkout is the standard action that clones your repository onto the Ubuntu runner so the script can access your files.
Step B: Prepare Java
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven
uses: actions/setup-java: Installs Java on the runner.
distribution: 'temurin': Specifies which vendor of Java to use (Eclipse Temurin is a popular choice).
cache: maven: This speeds up your build massively! It remembers your downloaded dependencies (JARs) so it doesn't have to re-download the internet every time the build runs.
Step C: Build the Microservices
- name: Build and Test Order Service
working-directory: ./OrderService
run: |
chmod +x mvnw
./mvnw clean verify
This is where the magic happens. Since you have a monorepo (multiple projects in one folder), we handle them separately.
working-directory: Tells the runner to cd (change directory) into ./OrderService before running commands.
chmod +x mvnw: Grants execution permission to the Maven Wrapper.
./mvnw clean verify: The command that actually builds your app.
Why mvnw and not mvn? The "Wrapper" ensures the build uses the exact Maven version defined in your project.
Why verify? In the Maven lifecycle, verify runs validation, compilation, unit tests, and integration tests. It is more robust than just install.
How to Set This Up in GitHub
Open your project locally or on GitHub.
Create the directory structure: Inside your project root, create a folder named .github and inside that, a folder named workflows.
Path: .github/workflows/
Create the file: Create a new file named ci.yml.
Paste the code: Copy the YAML code we analyzed above into this file.
Commit and Push:
git add .github/workflows/ci.yml
git commit -m "Add CI pipeline"
git push origin main
That's it!
Go to the "Actions" tab in your GitHub repository. You will see your workflow spinning up. If the circles turn Green, your code is safe. If they turn Red, you broke the build—and thankfully, you found out before your users did.
Sample Setup : https://github.com/Rohithv07/OnlineShopping/blob/main/.github/workflows/ci.yml
Top comments (0)