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
1 2 3 4 5 6 7 8 9 |
com.kscodes.springboot βββ controller β βββ HelloController.java βββ service β βββ GreetingService.java βββ KSCodesApplication.java |
π HelloController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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:
1 2 3 4 |
.github/workflows/springboot-ci.yml |
π οΈ springboot-ci.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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-reports
with test results - β Fails PRs on test failures
π§ Optional: Add Code Coverage with JaCoCo
Add to pom.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.8</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> |
This will produce target/site/jacoco/index.html
after test runs. You can optionally upload it to GitHub Artifacts:
1 2 3 4 5 6 7 8 9 |
- 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:
1 2 3 4 5 6 |
- 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