# 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。 - 支持草稿或预发布版本,便于测试和验证。 ## 注意事项 1. \*\*Maven 配置\*\*:确保项目包含有效的 \`pom.xml\` 文件。 2. \*\*JAR 文件路径\*\*:正确配置 \`jar_dir_prefix\` 以匹配项目结构。 3. \*\*GitHub 令牌\*\*:需要在 GitHub 仓库的 Secrets 中配置 \`PAT\`。 4. \*\*触发方式\*\*:支持通过推送标签(如 \`v1.0.0\`)或手动触发运行。 5. \*\*文件路径\*\*:配置文件必须位于项目路径 \`.github/workflows/build.yml\` 中,以确保 GitHub Actions 能够正确识别和执行。 ## build.yml 配置文件 以下是位于 \`.github/workflows/build.yml\` 的完整配置文件: \`\`\`yaml # 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/\` 目录下,以正确触发工作流程。