CI/CD for Java: Advanced GitHub Actions Configuration

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: From Basic Pipelines to Industrial Solutions



A basic CI/CD pipeline for a Java project is good. But in real development, when a project grows to dozens of modules and the team consists of several developers, a simple `mvn clean test` no longer meets the requirements. Questions arise: how to speed up the build? How to test on different JDK versions? How to organize parallel test execution? How to automatically publish artifacts to Docker Hub?



In this article, we will cover advanced techniques for configuring GitHub Actions for Java projects. You will learn how to turn your pipeline from a linear sequence of steps into a powerful, parallel, and optimized continuous integration and delivery system.



1. Matrix Builds: Testing on Multiple JDKs and OS



One of the key tasks of CI is to ensure that your Java code works on all supported platforms. Manually running tests on Windows, macOS, and Linux with different JDK versions (11, 17, 21) is an unaffordable luxury. GitHub Actions offers an elegant solution: matrix builds.



How It Works



You define a matrix of parameters (JDK versions, operating systems), and GitHub automatically creates a separate job for each combination. All of them run in parallel.



Configuration Example



name: Java CI Matrixon: [push, pull_request]

jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] java: [11, 17, 21] exclude: - os: windows-latest java: 21 # Exclude JDK 21 on Windows if not supported fail-fast: false # Do not stop other jobs if one fails

steps: - uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'temurin' - name: Build with Maven run: mvn -B clean verify --file pom.xml


Key Points:

  • strategy.matrix — defines parameter combinations.
  • exclude — allows you to exclude knowingly non-working or unnecessary combinations.
  • fail-fast: false — if one job fails, the others continue. This gives a complete picture of compatibility.


2. Dependency Caching: Speed Up Builds by 2-3 Times



Each pipeline run starts with a clean environment. Maven or Gradle downloads all dependencies from repositories anew. This can take 3-5 minutes. Caching solves this problem by saving the ~/.m2/repository folder (for Maven) or ~/.gradle/caches (for Gradle) between runs.



GitHub Actions provides a built-in action actions/cache. The cache key is formed based on the dependency file (pom.xml). If the file hasn't changed, the cache is restored instantly.



Example for Maven



steps:  - uses: actions/checkout@v4

- name: Cache Maven dependencies uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven-

- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin'

- name: Build with Maven run: mvn -B clean verify --file pom.xml


Important: Caching should come before the build step. The key hashFiles('**/pom.xml') ensures the cache is updated only when dependencies change.



3. Parallel Test Execution and Build Artifacts



When your project contains hundreds or thousands of tests, and

Blogs

Book Recommendations