Gradle多模块项目:如何在GitHub Actions多工作流共享Strategy Matrix?
解决方案:提取共享Strategy Matrix到可复用组件
针对你的多模块Gradle项目,以下是几种GitHub Actions原生支持的方案,能彻底解决重复复制模块名称的问题:
方案1:使用复合工作流(推荐)
这是GitHub官方推荐的复用方式,既能共享matrix配置,还能复用通用CI步骤,最适合你的场景。
步骤1:创建可复用工作流文件
在.github/workflows/目录下新建reusable-ci-base.yml,把包含matrix的通用CI逻辑放在这里:
name: Reusable CI Base on: workflow_call: outputs: job-status: description: "CI任务执行状态" value: ${{ jobs.ci.outputs.job-status }} jobs: ci: runs-on: ubuntu-latest outputs: job-status: ${{ steps.tests.outcome }} strategy: fail-fast: false matrix: design-pattern: [ "abstract-factory", "adapter", "bridge", "builder", "chain-of-responsibility", "command", "composite", "decorator", "facade", "factory-method", "flyweight", "iterator", "mediator", "observer", "prototype", "proxy", "singleton", "state", "static-factory-method", "strategy", "template-method", "visitor", ] steps: - name: 拉取代码 uses: actions/checkout@v4 with: fetch-depth: 0 - name: 安装Java uses: actions/setup-java@v3 with: java-version: 17 distribution: 'temurin' - name: 检测模块变更 uses: dorny/paths-filter@v2.11.1 id: changes with: filters: | source_code: - '.github/workflows/**' - '${{ matrix.design-pattern }}/src/**' - '${{ matrix.design-pattern }}/build.gradle.kts' - 'build.gradle.kts' - 'gradle/libs.versions.toml' - 'settings.gradle.kts' - 'gradle.properties' docs: - '${{ matrix.design-pattern }}/README.md' - README.md - name: Gradle构建与检查 if: steps.changes.outputs.source_code == 'true' id: tests env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew ${{ matrix.design-pattern }}:spotlessCheck ${{ matrix.design-pattern }}:build
步骤2:在主流水线中调用可复用工作流
修改你的ci.yml,直接引用上面的可复用工作流即可:
name: ci on: pull_request: types: [ opened, synchronize, reopened, ready_for_review ] jobs: call-reusable-ci: uses: ./.github/workflows/reusable-ci-base.yml ci-check: if: always() needs: - call-reusable-ci runs-on: ubuntu-latest steps: - name: 校验所有CI任务状态 uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }}
后续更新模块列表时,只需要修改reusable-ci-base.yml里的matrix,所有引用该工作流的流水线都会自动同步更新。
方案2:用JSON文件存储模块列表(灵活分离配置)
如果仅需要共享模块列表,不需要复用CI步骤,可以把模块列表单独存在JSON文件中,在流水线里动态读取生成matrix。
步骤1:创建模块列表文件
在仓库根目录新建modules.json:
{ "design-patterns": [ "abstract-factory", "adapter", "bridge", "builder", "chain-of-responsibility", "command", "composite", "decorator", "facade", "factory-method", "flyweight", "iterator", "mediator", "observer", "prototype", "proxy", "singleton", "state", "static-factory-method", "strategy", "template-method", "visitor" ] }
步骤2:在流水线中动态读取生成matrix
修改你的ci.yml,添加步骤读取JSON文件并生成matrix:
name: ci on: pull_request: types: [ opened, synchronize, reopened, ready_for_review ] jobs: generate-matrix: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - name: 拉取代码 uses: actions/checkout@v4 - name: 从JSON生成matrix id: set-matrix run: | MATRIX=$(jq -c '{ "design-pattern": ."design-patterns" }' modules.json) echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" ci: needs: generate-matrix runs-on: ubuntu-latest strategy: fail-fast: false matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} steps: # 以下为原有的CI步骤,与之前一致 - name: 拉取代码 uses: actions/checkout@v4 with: fetch-depth: 0 - name: 安装Java uses: actions/setup-java@v3 with: java-version: 17 distribution: 'temurin' - name: 检测模块变更 uses: dorny/paths-filter@v2.11.1 id: changes with: filters: | source_code: - '.github/workflows/**' - '${{ matrix.design-pattern }}/src/**' - '${{ matrix.design-pattern }}/build.gradle.kts' - 'build.gradle.kts' - 'gradle/libs.versions.toml' - 'settings.gradle.kts' - 'gradle.properties' docs: - '${{ matrix.design-pattern }}/README.md' - README.md - name: Gradle构建与检查 if: steps.changes.outputs.source_code == 'true' id: tests env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew ${{ matrix.design-pattern }}:spotlessCheck ${{ matrix.design-pattern }}:build ci-check: if: always() needs: - ci runs-on: ubuntu-latest steps: - name: 校验所有CI任务状态 uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }}
这个方案的优势是模块列表与流水线逻辑分离,其他工具(比如脚本、文档生成)也可以复用这个JSON文件。
方案对比
- 复合工作流:适合需要复用整套CI流程的场景,维护成本最低,一次更新全流水线生效。
- JSON文件+动态读取:适合仅需共享模块列表的场景,灵活性更高,配置与逻辑分离。
内容的提问来源于stack exchange,提问作者Yonatan Karp-Rudin
相关产品推荐
相关产品推荐

