CI/CD for Spring Boot (Maven) with GitHub Actions
A Spring Boot service with JPA needs integration tests against real Postgres before the jar is packaged and shipped.
This recipe builds a GitHub Actions pipeline for a Maven-based Spring Boot app. It runs mvn verify against a Postgres service, packages the jar, and deploys on main.
What the pipeline does
- Set up JDK with Maven cache
- mvn verify (compile, test, integration test)
- Run against Postgres
- Package the jar
- Deploy on main
The workflow
setup-java caches the Maven repository so dependency resolution is fast.
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: app_test
ports: ["5432:5432"]
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/app_test
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: postgres
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: maven
- run: mvn -B verify
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: maven
- run: mvn -B package -DskipTests
- run: ./deploy.sh target/app.jarTesting against a database
Spring Boot reads SPRING_DATASOURCE_* env vars, so point them at the postgres service at localhost:5432. For @SpringBootTest integration tests you can use the service container directly, or use Testcontainers - Docker is preinstalled on the runner, so Testcontainers works without extra setup. Flyway or Liquibase runs migrations at boot.
Deploying
mvn package produces an executable jar in target/. Deploy it as a container image, copy it to a VPS over SSH and run it under systemd, or push to a PaaS. Externalize secrets via environment variables, not application.properties.
Key takeaways
- cache: maven on setup-java caches ~/.m2 for fast resolution.
- mvn verify runs unit and integration tests; point the datasource at Postgres.
- Testcontainers works on the runner since Docker is preinstalled.