如何通过GitHub Actions动态按文件夹并行执行Java模块测试?
动态识别Java模块并在GitHub Actions中执行测试
当然不用手动维护所有Java模块的目录路径!你完全可以实现动态查找前缀为Java-的目录,然后自动在每个目录中执行测试,不用每次新增模块都修改工作流文件。下面是具体的实现方案:
核心思路
分两步走:
- 先通过一个前置Job动态发现所有符合命名规则的Java模块目录
- 利用GitHub Actions的矩阵功能,针对每个发现的目录单独执行测试
完整工作流示例
创建一个.github/workflows/java-test-pr.yml文件,内容如下:
name: Run Java Module Tests on PR on: pull_request: branches: [ main ] jobs: discover-java-modules: runs-on: ubuntu-latest outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - uses: actions/checkout@v4 - name: Find all Java-* modules id: set-modules run: | # 查找根目录下所有以Java-开头的一级目录,转成JSON数组 MODULES=$(find . -type d -name "Java-*" -maxdepth 1 | sort | jq -R . | jq -s .) echo "modules=$MODULES" >> $GITHUB_OUTPUT run-tests: needs: discover-java-modules runs-on: ubuntu-latest if: needs.discover-java-modules.outputs.modules != '[]' # 没有找到模块时跳过 strategy: matrix: module: ${{ fromJSON(needs.discover-java-modules.outputs.modules) }} fail-fast: false # 一个模块测试失败不影响其他模块 steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: maven # 如果用Gradle就改成gradle - name: Run tests in ${{ matrix.module }} run: | cd ${{ matrix.module }} ./mvnw test # 用Gradle的话改成 ./gradlew test
关键部分解释
- 目录发现Job:
- 用
find . -type d -name "Java-*" -maxdepth 1精准定位根目录下所有以Java-开头的一级子目录,maxdepth 1避免挖到嵌套的子目录 - 通过
jq把命令输出转换成GitHub Actions矩阵能识别的JSON数组格式,确保每个目录作为矩阵的一个单独项
- 用
- 测试执行Job:
- 通过
needs: discover-java-modules依赖目录发现Job,确保先拿到模块列表再执行测试 if条件判断避免在没有找到任何Java模块时触发无效的测试任务fail-fast: false保证某个模块测试失败时,其他模块的测试依然能继续执行,方便你一次性看到所有问题
- 通过
- 测试命令:这里用了Maven wrapper和Gradle wrapper的示例,你可以根据自己项目的构建工具调整
额外优化点
- 如果你的Java模块使用不同的JDK版本,可以在目录发现时额外收集版本信息,或者在测试Job中根据目录名动态选择JDK
- 可以添加缓存步骤,复用依赖包下载缓存,加快测试执行速度(示例中已经通过
setup-java的cache参数实现了基本缓存)
这样一来,不管你新增多少个Java-前缀的模块,工作流都会自动识别并执行对应的测试,完全不用手动更新工作流文件,完美适配你的仓库结构需求。
内容的提问来源于stack exchange,提问作者Jungdoo Lee




