多步骤并行阶段配置:单仓多服务流水线执行问询
完美适配你的Mono-Repo并行测试流水线方案
刚好我之前折腾过类似的mono-repo CI配置,完全懂你想要的效果——既要让每个服务的test和benchmark严格串行(test挂了就直接跳过benchmark),又要让不同服务的分支并行跑,还得把test和benchmark拆成独立阶段不混在一起。用group(或者对应CI工具的类似分组功能)完全能实现,给你一步步拆解:
核心思路
其实很简单:给每个服务单独建一个job分组,把该服务的test和benchmark放进同一个组里。这样每个组内部的两个阶段会严格串行(test过了才跑benchmark),不同组之间则是完全并行的。最后再整个统一的notify阶段,等所有服务的benchmark都跑完(且成功)才触发。
具体配置示例(以GitHub Actions为例)
我直接给你写个可复用的配置模板,你可以照着改:
name: Mono-Repo Parallel Test & Benchmark on: [push, pull_request] jobs: # -------------------------- # 服务1的专属job组 # -------------------------- svc1-test: name: 服务1 - 测试阶段 runs-on: ubuntu-latest group: svc1-workflow # 标记属于服务1的分组 steps: - uses: actions/checkout@v4 - name: 安装依赖并执行测试 run: | cd ./services/svc1 npm install # 这里换成你服务的依赖安装命令 npm test # 换成你的测试命令 svc1-benchmark: name: 服务1 - 基准测试阶段 runs-on: ubuntu-latest group: svc1-workflow needs: svc1-test # 关键:必须等服务1的test成功才执行 steps: - uses: actions/checkout@v4 - name: 安装基准测试依赖并执行 run: | cd ./services/svc1 npm install -g benchmark-cli # 这里可以单独装benchmark需要的依赖 npm run benchmark # 换成你的基准测试命令 # -------------------------- # 服务2的专属job组 # -------------------------- svc2-test: name: 服务2 - 测试阶段 runs-on: ubuntu-latest group: svc2-workflow steps: - uses: actions/checkout@v4 - name: 安装依赖并执行测试 run: | cd ./services/svc2 pip install -r requirements.txt # Python服务的依赖安装 pytest # Python测试命令 svc2-benchmark: name: 服务2 - 基准测试阶段 runs-on: ubuntu-latest group: svc2-workflow needs: svc2-test steps: - uses: actions/checkout@v4 - name: 安装基准测试依赖并执行 run: | cd ./services/svc2 pip install pytest-benchmark pytest --benchmark-autosave # -------------------------- # 最终通知阶段 # -------------------------- notify: name: 构建结果通知 runs-on: ubuntu-latest needs: [svc1-benchmark, svc2-benchmark] # 等所有服务的benchmark都完成 if: always() # 可选:不管构建成功失败都发通知,按需调整 steps: - name: 发送通知 run: | echo "构建状态:${{ job.status }}" # 这里可以加邮件、Slack、企业微信的通知逻辑
关键细节说明
- 分组的作用:每个服务的test和benchmark用同一个
group标记,CI工具会保证同一组内的job串行执行,不同组的job则并行跑,完全符合你要的分支流程。 - 失败快速终止:通过
needs关键字绑定test和benchmark,只要test失败,对应的benchmark会直接被标记为“跳过”,不会浪费资源去跑,而且整个构建会直接标记为失败,符合你“仅当所有服务分支成功才通过”的要求。 - 阶段隔离:test和benchmark是完全独立的job,你可以给它们配置不同的运行环境(比如test用Node 18,benchmark用Node 20)、不同的依赖,完全不用合并成一个阶段。
如果用的是GitLab CI,思路也是一样的,只是语法稍有不同:
stages: - test - benchmark - notify # 服务1的job svc1-test: stage: test tags: [ubuntu] script: - cd services/svc1 && npm install && npm test svc1-benchmark: stage: benchmark tags: [ubuntu] needs: [svc1-test] script: - cd services/svc1 && npm install -g benchmark-cli && npm run benchmark # 服务2的job svc2-test: stage: test tags: [ubuntu] script: - cd services/svc2 && pip install -r requirements.txt && pytest svc2-benchmark: stage: benchmark tags: [ubuntu] needs: [svc2-test] script: - cd services/svc2 && pip install pytest-benchmark && pytest --benchmark-autosave # 通知job notify: stage: notify tags: [ubuntu] needs: [svc1-benchmark, svc2-benchmark] script: - echo "流水线状态:$CI_JOB_STATUS"
GitLab CI会自动把同一stage下的job并行执行,然后通过needs控制同服务内的串行,最后notify等所有benchmark完成。
总结
这套方案完全贴合你的需求:
- 多服务分支并行执行,提升构建效率
- 单个服务test失败直接跳过benchmark,减少无效执行
- test和benchmark完全隔离,各自配置依赖和环境
- 只有所有服务的test+benchmark都成功,整体构建才会通过
内容的提问来源于stack exchange,提问作者QuantumLicht
相关产品推荐
相关产品推荐

