GitHub Actions Java 项目构建与发布流程
本文档介绍了一个使用 GitHub Actions 自动构建 Java 项目并发布为 ZIP 文件的完整工作流程。该工作流程基于 Maven 构建工具,能够根据用户输入的配置动态调整 Java 版本、是否跳过测试以及发布类型(草稿或预发布)。配置文件位于项目路径 .github/workflows/build.yml 中。以下是对工作流程的详细说明,并附上完整的 build.yml 配置文件。
工作流程概述
该 GitHub Actions 工作流程名为 Java Jar To Zip Publish,主要用于:
- 在推送带有
v*标签的分支或手动触发时运行。 - 构建 Java 项目,生成 JAR 文件。
- 将 JAR 文件打包为 ZIP 文件。
- 将 ZIP 文件及其内容上传到 GitHub Release。
工作流程支持以下用户输入参数:
- tag_name: Release 标签(如
v1.0.0,默认值为v-manual)。 - skip_tests: 是否跳过测试(
true或false,默认值为false)。 - java_version: Java 版本(如
8、11、17,默认值为8)。 - jar_dir_prefix: JAR 文件路径前缀(如
micro-service,默认值为空)。 - draft: 是否为草稿 Release(默认值为
false)。 - prerelease: 是否为预发布 Release(默认值为
false)。
工作流程步骤
以下是工作流程的详细步骤:
1. 检出代码
使用 actions/checkout@v4 动作将代码仓库检出到运行环境中,确保后续步骤能够访问项目文件。
2. 设置 Java 环境
通过 actions/setup-java@v4 配置指定版本的 Java 环境,默认使用 Eclipse Temurin 发行版。Java 版本由用户输入的 java_version 参数决定,默认为 8。
3. 缓存 Maven 依赖
使用 actions/cache@v4 缓存 Maven 依赖(位于 ~/.m2/repository),以加快构建速度。缓存的键基于操作系统和 pom.xml 文件的哈希值,确保依赖一致性。
4. 使用 Maven 构建并生成 JAR 文件
根据 skip_tests 参数决定是否跳过测试:
- 如果
skip_tests为true,运行mvn clean package -B -DskipTests -Dquickly。 - 否则,运行
mvn clean package -B -Dquickly。
-B参数启用批处理模式,-Dquickly用于加速构建。
5. 列出匹配的 JAR 文件
根据 jar_dir_prefix 参数查找生成的 JAR 文件:
- 如果
jar_dir_prefix为空,查找路径为*/target/*.jar的文件。 - 否则,查找路径为
*/${jar_dir_prefix}/*/target/*.jar的文件。
使用find命令列出匹配的文件,若未找到则输出提示信息。
6. 打包 JAR 文件为 ZIP
将所有匹配的 JAR 文件打包为一个 ZIP 文件,文件名为 jars-${tag_name}.zip。使用 zip -j 命令确保不保留目录结构,仅打包文件内容。
7. 验证 ZIP 文件
列出 ZIP 文件的详细信息并使用 unzip -l 显示其内容,确保打包正确。
8. 解压 ZIP 文件
将 ZIP 文件解压到 extracted-jars 目录,并列出解压后的文件列表,以便后续上传单独的 JAR 文件。
9. 上传到 GitHub Release
使用 softprops/action-gh-release@v2 将 ZIP 文件和解压后的 JAR 文件上传到 GitHub Release。Release 的元数据包括:
- 标签名称:
tag_name或默认的github.ref_name。 - Release 名称:根据
draft和prerelease参数动态添加“(Draft)”或“(Pre-release)”标记。 - Release 描述:包含标签名和 Java 版本等信息。
- 草稿状态:由
draft参数决定。 - 预发布状态:由
prerelease参数决定。
上传需要使用 GitHub 个人访问令牌(secrets.PAT)以确保权限。
权限配置
工作流程需要以下权限:
contents: write:用于创建和上传 Release。actions: read:用于执行 GitHub Actions 操作。
使用场景
该工作流程适用于以下场景:
- 自动化构建和发布 Java 项目,尤其是微服务架构项目。
- 需要灵活配置 Java 版本或跳过测试以加速构建。
- 希望将多个 JAR 文件打包为 ZIP 并同时上传单独的 JAR 文件到 GitHub Release。
- 支持草稿或预发布版本,便于测试和验证。
注意事项
- Maven 配置:确保项目包含有效的
pom.xml文件。 - JAR 文件路径:正确配置
jar_dir_prefix以匹配项目结构。 - GitHub 令牌:需要在 GitHub 仓库的 Secrets 中配置
PAT。 - 触发方式:支持通过推送标签(如
v1.0.0)或手动触发运行。 - 文件路径:配置文件必须位于项目路径
.github/workflows/build.yml中,以确保 GitHub Actions 能够正确识别和执行。
build.yml 配置文件
以下是位于 .github/workflows/build.yml 的完整配置文件:
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Java Jar To Zip Publish
run-name: "Jar ${{ github.event.inputs.tag_name || 'v-manual' }} version"
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag_name:
description: '输入 Release 标签 (如 v1.0.0)'
required: true
default: 'v-manual'
skip_tests:
description: '是否跳过测试 (true/false)'
required: true
type: boolean
default: false
java_version:
description: '输入 Java 版本 (如 8, 11, 17)'
required: true
default: '8'
jar_dir_prefix:
description: 'JAR 文件前缀 (如 micro-service 或留空)'
default: ''
draft:
description: '是否为草稿 Release (true/false)'
type: boolean
default: false
prerelease:
description: '是否为预发布 Release (true/false)'
type: boolean
default: false
jobs:
build-and-release:
runs-on: ubuntu-latest
permissions:
contents: write
#releases: write
actions: read
steps:
- name: 1.检出代码
uses: actions/checkout@v4
- name: 2.设置 Java 环境 version=${{ github.event.inputs.java_version || '8' }}
uses: actions/setup-java@v4
with:
java-version: ${{ github.event.inputs.java_version || '8' }}
distribution: 'temurin'
- name: 3.缓存 Maven 依赖
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: 4.使用 Maven 构建并生成 JAR
run: |
if [ "${{ inputs.skip_tests }}" = "true" ]; then
echo "跳过测试"
echo "mvn clean package -B -DskipTests -Dquickly"
mvn clean package -B -DskipTests -Dquickly
else
echo "mvn clean package -B -Dquickly"
mvn clean package -B -Dquickly
fi
echo "Maven 构建完成"
- name: 5.列出匹配的 JAR 文件
run: |
if [ "${{ inputs.jar_dir_prefix }}" = "" ]; then
echo "匹配的 JAR 文件 (*/target/*.jar):"
find . -type f -path "*/target/*.jar" || echo "未找到匹配的 JAR 文件"
else
echo "匹配的 JAR 文件 (*/${{ inputs.jar_dir_prefix }}/*/target/*.jar):"
find . -type f -path "*/${{ inputs.jar_dir_prefix }}/*/target/*.jar" || echo "未找到匹配的 JAR 文件"
fi
- name: 6.打包所有 JAR 文件成 ZIP
run: |
if [ "${{ inputs.jar_dir_prefix }}" = "" ]; then
find . -type f -path "*/target/*.jar" -exec zip -j jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip {} +
else
find . -type f -path "*/${{ inputs.jar_dir_prefix }}/*/target/*.jar" -exec zip -j jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip {} +
fi
# -j: 仅打包文件,不保留目录结构
# +: 尽量将多个文件放入一个 zip 命令,减少调用次数
shell: bash
- name: 7.验证 ZIP 文件
run: |
ls -la jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip
echo "ZIP 文件内容:"
unzip -l jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip
- name: 8.解压 ZIP 文件
run: |
mkdir -p extracted-jars
unzip jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip -d extracted-jars
echo "解压后的文件:"
ls -la extracted-jars
- name: 9.上传 ZIP 到 GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
jars-${{ github.event.inputs.tag_name || github.ref_name }}.zip
extracted-jars/*.jar
tag_name: ${{ github.event.inputs.tag_name || github.ref_name }}
name: Release ${{ github.event.inputs.tag_name || github.ref_name }} ${{ github.event.inputs.draft == 'true' && '(Draft)' || '' }} ${{ github.event.inputs.prerelease == 'true' && '(Pre-release)' || '' }}
body: |
**Release 信息**
- 标签: ${{ github.event.inputs.tag_name || github.ref_name }}
- Java 版本: ${{ github.event.inputs.java_version || '8' }}
# - 是否跳过测试: ${{ github.event.inputs.skip_tests == 'true' && '是' || '否' }}
# - Draft 状态: ${{ github.event.inputs.draft == 'true' && '是' || '否' }}
# - Pre-release 状态: ${{ github.event.inputs.prerelease == 'true' && '是' || '否' }}
draft: ${{ github.event.inputs.draft == 'true' || false }}
prerelease: ${{ github.event.inputs.prerelease == 'true' || false }}
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
总结
该 GitHub Actions 工作流程提供了一个高效、灵活的方式来自动化 Java 项目的构建、打包和发布流程。通过用户输入参数,可以轻松定制 Java 版本、测试策略和 Release 类型,适合各种规模的 Java 项目开发。确保将 build.yml 放置在项目路径 .github/workflows/ 目录下,以正确触发工作流程。