如何识别Github提交的变更文件夹,实现单仓CI/CD仅执行对应目录测试
实现单仓库多目录变更触发对应流水线的方案
核心思路
利用GitHub Actions的路径过滤规则结合脚本判断变更目录,仅执行对应目录的测试、构建流程,有两种常用实现方式,可根据你的项目复杂度选择:
方案1:使用官方路径过滤规则(适合目录划分固定的场景)
这种方式无需额外依赖,直接在workflow配置中定义路径触发规则,有两种写法可选:
写法1:多job单workflow,按路径判断是否执行
每个应用对应独立的job,只有对应目录下的文件变更时才会执行对应job,示例配置如下:
name: Monorepo CD Pipeline on: push: branches: [ main ] jobs: test-app1: runs-on: ubuntu-latest # 只有app1目录下有变更时才执行该job if: ${{ github.event_name == 'push' && contains(join(github.event.commits.*.modified, ','), 'app1/') }} steps: - uses: actions/checkout@v4 - name: 执行app1测试 run: | cd app1 npm install npm run test test-app2: runs-on: ubuntu-latest # 只有app2目录下有变更时才执行该job if: ${{ github.event_name == 'push' && contains(join(github.event.commits.*.modified, ','), 'app2/') }} steps: - uses: actions/checkout@v4 - name: 执行app2测试 run: | cd app2 mvn test
写法2:单应用单workflow,触发规则直接限制路径
每个应用对应独立的workflow文件,比如.github/workflows/app1-cd.yml的触发规则配置如下:
on: push: branches: [ main ] paths: - 'app1/**'
只有app1目录下的文件变更时才会触发整个app1的workflow,不需要额外写if判断,配置更简洁。
方案2:使用变更检测脚本动态执行任务(适合目录多、变动频繁的场景)
如果应用数量多,逐个写job或workflow配置太繁琐,可以写统一的检测脚本,遍历所有变更文件匹配目录,批量执行对应任务:
- 拉取全量代码用于对比提交差异
- 执行git diff命令获取本次提交的所有变更目录
- 遍历变更目录列表,判断每个目录是否为有效应用目录,存在测试脚本就执行对应测试
示例配置如下:
jobs: test-changed-apps: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # 拉取全量提交历史用于diff对比 - name: 检测变更目录并执行测试 run: | # 获取所有变更的一级应用目录,可根据你的目录层级调整cut参数 CHANGED_APPS=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | cut -d'/' -f1 | sort | uniq) for app in $CHANGED_APPS; do # 判断该目录是否为有效应用目录,可根据项目规则调整判断条件,比如是否存在pom.xml/package.json if [ -d "$app" ] && [ -f "$app/package.json" ]; then echo "执行 $app 目录的测试" cd $app npm install npm run test cd .. fi done
注意事项
- 拉取代码时如果要对比历史提交,需要设置
fetch-depth: 0,否则默认只拉取最新一次提交,无法做diff对比 - 如果你用的是PR触发的流水线,可以把diff的对比基准改成
origin/${{ github.base_ref }} - 可以根据需要调整目录匹配的层级,比如你的应用都放在
apps/目录下,就把cut的参数改成取第二级目录即可
内容的提问来源于stack exchange,提问作者Guusda
相关产品推荐
相关产品推荐

