CircleCI Ruby on Rails示例配置为何设置非DRY的build与test两个独立job
你的判断存在几个容易忽略的考量点,拆分build、test两个job不是冗余设计,核心价值包括:
- 大幅降低并行测试的资源消耗
示例中test job设置了parallelism: 3,会启动3个并行实例执行测试。如果没有单独的build job预先生成依赖缓存,3个test实例会各自执行一遍Ruby依赖安装、Node依赖安装的步骤,重复消耗网络和计算资源。而单独先跑1次build job,它生成的全局缓存会被所有后续test实例直接复用,test中的ruby/install-deps、node/install-packages步骤只会做缓存校验,不会真的重新下载安装依赖,总耗时和资源成本远低于3个实例重复安装。 - 更快的失败反馈,降低无效资源开销
test job需要启动包含Ruby+Node+PostgreSQL的多容器环境,启动速度远慢于只有单基础镜像的build job。如果存在代码拉取失败、依赖版本冲突、依赖源不可用这类基础问题,在build阶段就能提前拦截报错,不需要等到3个测试容器全部启动、执行到前置步骤才发现问题,既缩短了错误反馈时间,也避免了测试容器的无效运行开销(多数CI服务是按容器运行时长计费的)。 - 更高的流水线扩展灵活性
拆分的build job是可复用的基础节点,后续如果需要新增代码lint、安全漏洞扫描、静态类型检查、镜像打包等不需要数据库的任务,都可以直接依赖build job的成功状态和它生成的缓存,不需要每个新增job都重复编写依赖安装的步骤,也避免了重复执行安装逻辑的开销。另外如果后续要加部署流程,也可以直接基于build阶段的产物继续执行,不需要跑完整的测试流程。 - 更清晰的问题定位边界
流水线失败时,单独的job拆分可以快速定位问题类型:build失败就直接排查代码拉取、依赖安装相关的问题,test失败就排查数据库配置、测试用例相关的问题,不需要在test job的冗长日志里翻找定位是前置基础步骤出错还是测试本身出错。
你看到的两个job步骤看起来完全一致,是官方示例为了可读性做的简化,实际生产中还可以把asset编译这类构建操作放到build job里,test job直接复用编译好的静态资源,进一步减少重复操作。
内容的提问来源于stack exchange,提问作者Chiperific
相关产品推荐
相关产品推荐

