Introduction to CI/CD for Java Projects with GitHub Actions
Modern software development is impossible without automation of build, testing, and deployment processes. CI/CD (Continuous Integration / Continuous Deployment) is a set of practices that allows teams to deliver changes to production quickly and safely. For Java projects, one of the most convenient tools is GitHub Actions — a built-in CI/CD system that does not require setting up a separate server.
In this article, we will walk through how to set up a pipeline for a Java application: from compilation and running tests to publishing artifacts. You will learn how to use Maven, JUnit, and GitHub Actions to create a reliable delivery process.
1. GitHub Actions Basics: Workflow Structure
GitHub Actions is based on workflows — configuration files in YAML format stored in the .github/workflows folder. Each workflow consists of one or more jobs that run on virtual machines (runners).
For a Java project, a typical workflow includes the following steps:
- Checkout — cloning the repository
- Setup JDK — installing the required Java version
- Cache — caching Maven/Gradle dependencies to speed up the build
- Build & Test — compilation and running tests
- Deploy — publishing artifacts (optional)
Let's look at a basic configuration example for Java 17 and Maven:
name: Java CI with Maven
on: push: branches: [ "main" ] pull_request: branches: [ "main" ]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: maven
- name: Build with Maven run: mvn -B package --file pom.xml
- name: Run tests run: mvn test
- name: Upload JAR artifact uses: actions/upload-artifact@v4 with: name: app-jar path: target/*.jarThis workflow runs on every push or pull request to the main branch. It builds the project, runs tests, and saves the JAR file as an artifact.
2. Advanced Setup: Testing and Code Quality
A simple build is just the beginning. In real projects, it is important to control code quality. Let's add steps for static analysis and report generation to the workflow.
First, let's integrate JaCoCo to measure test code coverage. Add the plugin to pom.xml:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.11</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>Now, let's update the workflow by adding coverage checks and publishing the report:
- name: Run tests with coverage run: mvn verify
- name: Upload JaCoCo report uses: actions/upload-artifact@v4 with: name: coverage-report path: target/site/jacoco/You can also add a linter like Checkstyle or SpotBugs. Example for Checkstyle:
- name: Checkstyle run: mvn checkstyle:checkThese steps will help automatically identify issues in