Skip to content
Latchkey

CI/CD for a Micronaut + GraalVM App with GitHub Actions

Test on the JVM, build a Micronaut native image with Gradle, and deploy.

Micronaut does dependency injection at compile time, which pairs well with GraalVM native images. This recipe runs JVM tests, then builds the native executable via the Gradle nativeCompile task.

What the pipeline does

  • set up a GraalVM JDK
  • run JVM tests with gradle test
  • build the native binary with nativeCompile
  • build the native Docker image
  • push the image for deploy

The workflow

The Micronaut Gradle plugin wires the GraalVM nativeCompile and dockerBuildNative tasks. setup-graalvm provides native-image and caches Gradle artifacts.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: graalvm/setup-graalvm@v1
        with:
          java-version: 21
          distribution: graalvm
          cache: gradle
      - run: ./gradlew test
      - run: ./gradlew nativeCompile
      - run: ./gradlew dockerBuildNative
      - name: Push image
        if: github.ref == 'refs/heads/main'
        run: |
          echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker push ghcr.io/${{ github.repository }}:latest

Caching and speed

cache: gradle restores ~/.gradle. nativeCompile is the expensive step; running it on cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) keeps native CI affordable, and auto-retry covers transient toolchain download failures so a flaky build does not block the merge.

Deploying

dockerBuildNative produces a small native-image container. Push it and deploy where fast startup matters: AWS Lambda (with the custom runtime), Cloud Run, or Knative for scale-to-zero workloads.

Key takeaways

  • Micronaut does DI at compile time, which suits GraalVM native images.
  • gradle nativeCompile and dockerBuildNative come from the Micronaut plugin.
  • Native containers are tiny and start fast, ideal for serverless.

Related guides

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