大规模CI/CD:应对Monorepo混乱的智能流水线

本文深入探讨了在大型Monorepo环境中实施CI/CD的最佳实践,包括受影响构建、远程缓存、AI辅助测试选择和基础设施即代码集成等关键技术,帮助团队提升部署效率并减少构建时间。

大规模CI/CD:应对Monorepo混乱的智能流水线

你是否曾看着一个大型Monorepo心想:“我到底该怎么搞CI/CD?“如果是这样,你并不孤单。我曾经也面临过这种情况——在无尽的服务、共享库和部署目标中摸索。最终,通过正确的技术和工具,CI/CD从怪物变成了机器。

让我分享从基础概念到生产就绪的旅程,帮助你优化流水线,并学到一两个之前没想过的东西。

为什么CI/CD在Monorepo中更复杂

Monorepo有以下优势:

  • 跨前端和后端的代码重用
  • 原子变更,在单个PR中更新多个服务/库
  • 一致的工具和代码质量

但这些优势也带来挑战:

  • 可扩展性:更改一个文件可能触发所有内容的构建/测试
  • 测试范围:确定需要运行哪些测试可能很棘手
  • 部署:更改一个小工具不应自动部署不相关的服务

允许流水线在每次提交时运行会阻碍团队的速度。正确的答案是让CI/CD更智能——不仅是自动化,还要了解代码库的结构和历史。

可扩展的CI/CD模式

以下是构建真正关心重要内容的流水线的方法:

1. 仅受影响构建

实现像Nx、TurboRepo、Bazel或自定义脚本这样的工具来分析提交中的更改,并仅构建/测试受影响的模块。这将CI摩擦转移到数据发现上。

2. 流水线矩阵

使用GitHub Actions、GitLab CI或CircleCI来并行化作业,即为每个受影响的服务/包设置一个作业。这以逻辑方式分解工作以加速。

3. 增量工作流

在模块级别实现缓存。在CI运行时,首先检查缓存命中。如果有缓存命中,则重用构建工件并跳过冗余步骤。如果没有缓存命中,则重新构建或重新测试并填充缓存。

如果不使用仅受影响构建,你的Monorepo有被自身重量压垮的风险。

AI辅助的CI流水线

添加AI可以将好的流水线变得更好。许多这些工具对开发人员速度和调试速度有直接影响。

智能测试选择

有工具(如与LLMs结合使用的CodeQL)可以分析差异和历史测试结果(通过提交哈希)来确定并最佳猜测哪些测试可能会失败,仅运行这些测试。这节省时间并减少来自不相关失败的噪音。

Copilot驱动的YAML片段

曾希望CI配置开箱即用吗?GitHub Copilot将根据仓库中的常见模式指示YAML工作流标准片段。它有潜力加速入职并标准化跨团队的流水线。

失败根因建议

很酷的想法:使用LLMs解析/记录和标记失败的日志以建议失败原因。想象一下打开PR并获得基于相关数据的自动化假设,说明测试失败的原因。这是生产力的胜利!

即将到来的功能

  • 大型语言模型在应用前生成和验证Terraform计划。
  • 给定一个损坏的流水线,我的编码代理可以检测失败的测试、代码差异,然后打开PR来修复测试、更新模拟等。
  • 自动检测任何新添加的下游依赖、配置更新,并建议添加新规则。

大规模远程缓存

本地缓存很酷。远程缓存使它们更强大。

  • 像Nx Cloud和TurboRepo Remote Cache这样的工具将构建/测试/lint结果存储在某个服务器上。
  • 缓存将在开发人员和CI运行之间共享,甚至跨不同的云区域。

示例:如果你的PR只更改了文档,CI可能会从缓存中提取所有构建和测试,因此几乎是即时的。如果你只编辑一个服务,只有该缓存将失效。其他所有内容?从缓存中提取。这也是一个令人难以置信的时间节省器,在大规模情况下——仅此一项就可以将大型仓库的总流水线时间减少60-80%。

CI/CD中的边缘部署

将代码部署到边缘网络(Cloudflare Workers、Vercel Edge)会增加更多复杂性:

  • 你的后端API将部署到哪里?在AWS或GCP上的Docker中。
  • 边缘函数将有特殊的编译和CDN部署
  • 静态资产——它们去哪里?S3、Redis、无头CMS

最佳实践

  • 基于路径的结构:apps/api、apps/edge、apps/web
  • 为此分离生产构建/部署工作流;每个目标一个流水线
  • 使用提供商的预览环境来测试每个PR(Vercel、Netlify)
  • 到目前为止,强调缓存和受影响构建——边缘用例需要快速迭代

CI中部署的基础设施

CI不仅交付代码;它还交付基础设施。

如果你从Monorepo使用Terraform、Pulumi或AWS CDK,你可以:

  • 一个PR可以更新你的Lambda函数源代码及其内存分配。
  • 你可以在合并前在PR中包含预览计划。
  • CI可以运行漂移检测,因此当实时云中的基础设施出现分歧时可以提醒你。

基础设施即代码的典型CI步骤

  • 运行terraform fmt和terraform validate。
  • 创建Terraform计划并将其作为评论添加到PR上。
  • 可选地,通过手动批准或合并来限制Terraform apply。
  • 观察和跟踪随时间推移的漂移。

这种集成级别允许更安全、更可预测和更可追踪的部署。

生产就绪的CI/CD清单

以下是你可以用来使CI/CD更生产级的项目列表:

  • 流水线仅运行受影响的构建和测试。
  • 如果可能,跨构建/运行和开发机器的远程缓存。
  • 非冲突配置流水线应并行运行,即矩阵构建。
  • 为边缘、后端、前端分离流水线/自定义。
  • 基础设施即代码、验证和门控的Terraform应用工作流。
  • 流水线为所有拉取请求生成预览部署以进行测试和验证。
  • 所有部署都应具有回滚路径的标签。
  • 所有部署都应通过Slack或GitHub评论通知,更新也应传播到待命频道。

结论

Monorepos很大,但这并不意味着我们的CI/CD也应该很大!我们的流水线应该更智能,而不是更大。使用AI、远程缓存、边缘和基础设施即代码对于开发人员的理智是强制性和至关重要的。我将留下以下问题:

  • 你是否基于模块或历史失败实施了测试选择?
  • 你是否考虑过在git设置中包含边缘函数流水线?
  • 你是否将Terraform应用步骤置于批准之后?
  • 你是否考虑过创建受影响构建图?

请分享你的学习、成功、失败或惊喜时刻!让我们一起创建更智能、更好的系统。

常见问题解答

问:如何知道PR影响了哪些包? 查看Nx、TurboRepo,或制作脚本解析依赖图。它们会准确告诉你哪些项目受到更改文件的影响。

问:缓存值得花时间设置吗? 是的,非常值得!对于大型Monorepos,缓存可以将CI时间减少60-80%,从而实现精益和敏捷的流水线(即使最初设置需要几个小时)。

问:如果我在GitLab或CircleCI上,还能使用AI吗? 是的。虽然Copilot是GitHub原生的,但基于AI的测试选择器和根因分析器等工具可以通过CLI、webhook或脚本在任何CI平台上集成。

问:我应该何时使用预览环境? 在每个PR上。一个短暂的、可注入的URL使审阅者和利益相关者能够在上下文中验证更改,在周期早期检测问题。

问:增量构建和远程缓存有什么区别? 增量构建将重用单台机器的输出,而远程缓存将在开发人员和CI运行之间共享构建输出结果,允许流水线运行更快、效率更高。

问:如何在CI中处理terraform apply? 在CI中使用terraform plan显示正在更改的内容,包括在PR上。然后设置批准要求,要求某人在运行terraform apply之前批准——通过合并或手动门控。

问:如果我只做文档更改,是否仍应等待完整CI? 使用仅受影响构建和缓存,CI应该能够获取更改的范围。如果CI可以确定只是文档,CI应该能够命中缓存并在几秒钟内完成。无需运行完整流水线。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计