In todayβs fast-paced development cycle, Continuous Integration (CI) and Continuous Deployment (CD) are essential for building reliable, testable, and deployable applications.
In this post, we’ll walk you through integrating Spring Boot CI/CD with GitHub Actions. Youβll learn how to:
- Set up automated tests and builds
- Generate test reports
- Run integration and unit tests
- Use best practices for GitHub workflow design
We’ll use a sample project in the package com.kscodes.springboot.

π§Ύ Project Structure
com.kscodes.springboot
βββ controller
β βββ HelloController.java
βββ service
β βββ GreetingService.java
βββ KSCodesApplication.java
π HelloController.java
package com.kscodes.springboot.controller;
import com.kscodes.springboot.service.GreetingService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class HelloController {
private final GreetingService service;
public HelloController(GreetingService service) {
this.service = service;
}
@GetMapping("/hello")
public String sayHello() {
return service.greet();
}
}
π GreetingService.java
package com.kscodes.springboot.service;
import org.springframework.stereotype.Service;
@Service
public class GreetingService {
public String greet() {
return "Hello from KSCodes!";
}
}
β Test File Example
π GreetingServiceTest.java
package com.kscodes.springboot.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class GreetingServiceTest {
@Test
public void shouldReturnGreeting() {
GreetingService service = new GreetingService();
assertEquals("Hello from KSCodes!", service.greet());
}
}
π§ͺ Step 1: Add GitHub Actions Workflow
Create a workflow file at:
.github/workflows/springboot-ci.yml
π οΈ springboot-ci.yml
name: Spring Boot CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Build with Maven
run: mvn -B clean verify
- name: Upload Test Report
if: always()
uses: actions/upload-artifact@v3
with:
name: junit-report
path: target/surefire-reports/
π Output from Workflow
- β
Runs
mvn clean verify - β Executes unit tests and integration tests
- β
Uploads
surefire-reportswith test results - β Fails PRs on test failures
π§ Optional: Add Code Coverage with JaCoCo
Add to pom.xml:
org.jacoco
jacoco-maven-plugin
0.8.8
prepare-agent
report
test
report
This will produce target/site/jacoco/index.html after test runs. You can optionally upload it to GitHub Artifacts:
- name: Upload Coverage Report
if: always()
uses: actions/upload-artifact@v3
with:
name: jacoco-report
path: target/site/jacoco/
π§ Best Practices for Spring Boot CI/CD with GitHub Actions
| Practice | Benefit |
|---|---|
β
Use verify not just test | Includes linting, integration checks |
| β Separate jobs for test/build/deploy | Better control and caching |
| β Use conditional upload of artifacts | Only when needed (if: always()) |
| β Add coverage badges in README | Transparency on code quality |
| β Fail fast on test failures | Prevent bad code from merging |
π Deployment (Optional CI/CD)
If you want to auto-deploy on a successful build:
- name: Deploy to Heroku (or DockerHub, AWS, etc)
run: |
echo "Add your deployment commands here"
Or use GitHub Actions integrations with:
- DockerHub (
docker/build-push-action) - AWS Elastic Beanstalk / ECS
- Azure App Service
- Kubernetes via
kubectl
π Summary
You now have a complete working pipeline for Spring Boot CI/CD with GitHub Actions! In this post, you:
- Created a working Spring Boot project with tests
- Set up GitHub Actions to automate builds and test reports
- Learned best practices for reliable and maintainable CI/CD pipelines