Skip to content
Latchkey

CI/CD for Spring Boot (Gradle) with GitHub Actions

A Gradle Spring Boot service tests against real Postgres, then assembles a bootJar for deploy.

This recipe wires a Gradle-based Spring Boot app into GitHub Actions. It runs ./gradlew test against Postgres, builds the bootJar, and deploys on main.

What the pipeline does

  • Set up JDK
  • Cache Gradle via gradle/actions
  • ./gradlew test against Postgres
  • bootJar
  • Deploy on main

The workflow

gradle/actions/setup-gradle handles the Gradle build cache and wrapper validation.

.github/workflows/ci.yml
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'
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew test
  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'
      - uses: gradle/actions/setup-gradle@v4
      - run: ./gradlew bootJar
      - run: ./deploy.sh build/libs/app.jar

Testing against a database

The postgres service is reachable at localhost:5432; Spring Boot picks it up from SPRING_DATASOURCE_*. For @SpringBootTest you can hit the service directly or use Testcontainers, which works because Docker ships on the runner. setup-gradle restores the build and dependency cache so reruns are fast.

Deploying

./gradlew bootJar produces build/libs/app.jar. Deploy it as a container, copy it to a VPS over SSH, or push to a PaaS. Provide secrets through environment variables at runtime.

Key takeaways

  • Use gradle/actions/setup-gradle for caching and wrapper validation.
  • ./gradlew bootJar produces the runnable jar in build/libs/.
  • Point SPRING_DATASOURCE_* at the postgres service for integration tests.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →