JVM 项目的 CI 不仅要编译和测试,还要处理复杂的依赖图、多 JDK 兼容性、代码覆盖率报告和容器化发布。Maven 和 Gradle 的依赖缓存策略直接决定 CI 速度,JaCoCo 和 SonarCloud 提供质量门禁,Jib 让 Java 应用无需 Dockerfile 即可构建优化过的容器镜像。本文覆盖 JVM 生态完整的 GitHub Actions CI 方案。
一、Maven CI 流水线
1.1 基础工作流
# .github/workflows/maven.yml
name: Java CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [8, 11, 17, 21]
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: 'maven'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Run tests
run: mvn -B test
- name: Generate coverage
run: mvn -B jacoco:report
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./target/site/jacoco/jacoco.xml
1.2 关键配置
actions/setup-java 的 cache: 'maven' 自动处理 ~/.m2/repository 缓存
distribution 选项:temurin(Eclipse Adoptium)、zulu、oracle、corretto
temurin 是开源免费的首选
二、Gradle CI 流水线
2.1 基础工作流
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build --no-daemon
- name: Run tests
run: ./gradlew test --no-daemon
- name: Generate coverage
run: ./gradlew jacocoTestReport --no-daemon
2.2 Gradle 缓存优化
cache: 'gradle' 自动处理:
- ~/.gradle/caches
- ~/.gradle/wrapper
额外优化:
- 使用 Gradle Build Cache(远程共享构建缓存)
- 配置 org.gradle.caching=true
- 使用 Gradle Enterprise 缓存节点
三、代码覆盖率与质量门禁
3.1 JaCoCo 配置
<!-- 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>
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
3.2 SonarCloud 集成
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
3.3 静态分析
<!-- SpotBugs -->
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.0</version>
</plugin>
<!-- Checkstyle -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<!-- PMD -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.21.2</version>
</plugin>
四、Jib 容器化构建
4.1 Maven Jib
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<from>
<image>eclipse-temurin:17-jre</image>
</from>
<to>
<image>ghcr.io/${env.GITHUB_REPOSITORY}:${project.version}</image>
</to>
</configuration>
</plugin>
- name: Build container with Jib
run: mvn compile jib:build -Djib.to.auth.username=${{ github.actor }} -Djib.to.auth.password=${{ secrets.GITHUB_TOKEN }}
4.2 Gradle Jib
plugins {
id 'com.google.cloud.tools.jib' version '3.4.0'
}
jib {
from {
image = 'eclipse-temurin:17-jre'
}
to {
image = "ghcr.io/${System.getenv('GITHUB_REPOSITORY')}:${version}"
}
}
4.3 Jib 优势
无需 Dockerfile:自动分析项目依赖构建优化镜像
分层缓存:依赖层独立,代码变更只重建应用层
多架构:支持构建 amd64/arm64 镜像
Registry 直连:不依赖本地 Docker daemon
五、多模块 Maven CI
5.1 模块矩阵构建
strategy:
matrix:
module: [core, api, web]
steps:
- uses: actions/checkout@v4
- name: Build ${{ matrix.module }}
run: mvn -pl ${{ matrix.module }} -am clean install
# -pl = projects list, -am = also make dependencies
5.2 依赖顺序管理
-am(--also-make):自动构建依赖模块
-amd(--also-make-dependents):构建当前模块及依赖它的模块
-rf(--resume-from):从指定模块恢复构建
# 配合 changes 检测:只改动的模块及其依赖才构建
六、性能基准测试(JMH)
6.1 JMH 自动化
- name: Run JMH benchmarks
run: mvn -Pbenchmark test
- name: Store benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'jmh'
output-file-path: target/jmh-results.json
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
6.2 基准测试仓库
benchmark-action/github-action-benchmark 支持:
- 将 benchmark 结果提交到 gh-pages 分支
- 自动生成性能趋势图
- 检测 regression(性能衰退自动告警)
七、发布到 Maven Central
7.1 发布配置
- name: Publish to Maven Central
run: mvn deploy -DskipTests
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
7.2 签名要求
Maven Central 要求:
- GPG 签名所有 artifact
- pom.xml 含 license/scm/developer 信息
- sources.jar 和 javadoc.jar
# 用 Maven GPG Plugin 自动签名
# GPG 密钥存 GitHub Secrets
八、Kotlin/Scala 混合项目
8.1 Kotlin 项目
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Run Kotlin tests
run: ./gradlew test ktlintCheck detekt
8.2 Scala 项目
- name: Set up Scala
uses: olafurpg/setup-scala@v14
with:
java-version: adopt@1.11
- name: Run SBT tests
run: sbt clean coverage test coverageReport
总结
JVM 项目的 GitHub Actions CI 核心 pipeline 是:检出代码 → setup-java(带 Maven/Gradle 缓存)→ mvn/gradle build → 运行测试 → JaCoCo 覆盖率 → SpotBugs/Checkstyle 静态分析 → SonarCloud 质量门禁 → Jib 容器化 → 发布到 Maven Central/GHCR。矩阵测试覆盖 JDK 8/11/17/21 确保兼容性,多级缓存(依赖缓存 + Build Cache)让 CI 时间从 10 分钟降到 2 分钟。Jib 是 JVM 容器化的最佳实践——无需 Dockerfile、自动分层、更快构建。Monorepo 用 -pl/-am 参数精确控制模块构建范围。
延伸阅读:
- GitHub Actions Python CI — Python CI 对比
- GitHub Actions PR 自动化 — 发布自动化
- Java 性能优化专题 — JVM 性能进阶
- Docker 专题 — 容器化深入
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。