Slack如何优化端到端测试流水线:构建时间减半的技术实践

本文详细介绍了Slack开发体验团队如何通过条件性前端构建和预构建资产缓存策略,将端到端测试流水线的构建时间从10分钟缩短至2分钟,同时显著降低了云存储成本和测试不稳定性。

在 DevOps 和开发者体验(DevXP)领域,速度和效率对工程师的日常工作有着重大影响。今天,我们将深入探讨 Slack 的 DevXP 团队如何利用现有工具优化端到端(E2E)测试流水线。这一优化降低了构建时间,减少了冗余流程,为 Slack 的工程师节省了时间和资源。

问题:不必要的前端构建

对于我们最大的代码仓库之一(单体仓库),Slack 设有一个 CI/CD 流水线,在将代码合并到 main 分支之前运行 E2E 测试。这对于确保 Slack 应用程序的整个技术栈(前端、后端、数据库以及中间的一些服务)的变更得到验证至关重要。然而,我们注意到了一个瓶颈:构建前端代码花费的时间比预期更长,并且发生得过于频繁,即使在没有前端相关变更的情况下也是如此。流程分解如下:

  1. 开发者工作流:开发者进行更改并推送到分支。
  2. 构建过程:构建前端代码(约5分钟)。
  3. 部署:将构建部署到 QA 环境。
  4. 测试:运行超过 200 项 E2E 测试,再花费 5 分钟。

整个过程每次运行大约需要 10 分钟。其中约一半时间(约 5 分钟)被前端构建消耗,即使在没有前端变更的情况下也是如此。

考虑到每天有数百个拉取请求(PR)被合并,这些冗余构建不仅耗时,而且成本高昂:

  • 每周数千次前端构建,每次构建在 AWS S3 中存储近千兆字节的数据。
  • 其中一半的构建与上次合并到 main 相比不包含前端变更,导致数 TB 的重复数据。
  • 每次构建 5 分钟,给流水线增加了不必要的延迟(每周数千小时)。

解决方案:采用更智能的构建策略与缓存前端资产

为了解决这个问题,我们利用现有工具重新思考了构建策略。

步骤 1:条件性前端构建

我们的第一步是判断是否需要全新的前端构建。我们通过使用 git diff 及其三点表示法来检测当前检出分支与 main 分支最新共同提交之间的差异。如果检测到变更,则触发前端构建任务;如果未检测到变更,则完全跳过构建并重用预构建版本。

步骤 2:预构建资产与内部 CDN

当不需要前端构建时,我们从 AWS S3 定位现有的构建。为了高效,我们使用仍在生产环境中使用的近期前端构建。我们将为 E2E 测试提供预构建前端资产的任务委托给一个内部 CDN。这减少了在每个 PR 上创建新构建的需求,同时仍确保我们在当前资产上进行测试。

挑战:规模化效率

虽然方法看似直接,但将该解决方案扩展到我们的单体仓库时遇到了一些挑战:

  • 识别前端变更:我们的仓库包含超过 10 万个被跟踪的文件。判断是否存在前端变更需要高效的文件跟踪,而 Git 仅用几秒钟就处理完毕。
  • 寻找预构建资产:每天有数百个 PR 合并到此仓库中,识别足够新的预构建版本需要强大的资产管理。通过使用简单的 S3 存储概念,我们能够在新鲜度、一致的文件命名和性能之间取得平衡来管理资产。
  • 保持快速:我们能够在平均不到 3 秒的时间内判断前端构建是否不必要,并找到近期的构建产物。

结果:构建频率降低 60%,构建时间减少 50%

我们的努力取得了显著成效:

  • 构建频率降低 60%:通过智能重用预构建的前端资产,我们将不必要的前端构建次数减少了一半以上。
  • 每月节省数百小时:减少了云计算时间和开发者的等待时间。
  • 节省数 TB 存储空间:我们每月减少了数 TB 的 AWS S3 存储。这些重复资产原本会存储一年。
  • 构建时间改善 50%:这是前端 DevXP 团队及其合作团队的第二个主要项目。第一个项目升级了我们的 Webpack 设置,将平均构建时间从约 10 分钟减少到约 5 分钟。本项目将平均构建时间从约 5 分钟进一步降至仅约 2 分钟。两个项目均成功,我们将 E2E 流水线的平均构建时间从约 10 分钟缩短到约 2 分钟:这是今年的一项巨大改进!

两个意外成果:

  1. 更可靠和可信的 E2E 结果:我们的测试不稳定性(指测试在没有代码变更的情况下间歇性或不一致地失败)显著降低。这一改进得益于优化的流水线、减少复杂前端构建的需求以及一致的资产交付。根据月度测量,我们观察到了最低的测试不稳定性百分比。
  2. 重新发现遗留代码:实施此优化需要深入探究多个系统长时间未重大修改的遗留代码。这次探索产生了宝贵的见解,引发了关于代码库行为的新问题,并为未来的改进生成了一系列待办任务。

结论:重新思考前端构建效率

通过战略性地利用 git diff 和内部 CDN 等现有工具,我们成功节省了宝贵的开发者时间,降低了云成本,并提高了整体构建效率。

对于其他公司面临 DevOps 和 DevXP 类似瓶颈的团队,教训是质疑流水线中真正必要的部分并进行相应优化。这个项目的改进事后看来似乎显而易见,但在尚未完全失效的系统中,低效之处常被忽视。在我们的案例中,重新思考我们处理前端资产的方式为组织带来了巨大的成功。

致谢

像这样的项目涉及许多环节:复杂的构建和测试流水线、云基础设施、内部 CDN、前端代码的复杂构建系统,以及我们整个系统中的现有自定义设置。它包括用 Python、JavaScript、Bash、PHP/Hack、Rust、YAML 和 Ruby 编写的代码。我们在没有任何停机的情况下实现了这一目标!好吧,几乎是这样。我们的部署流水线有十分钟的内部停机时间,但很快得到了修复。

这项工作离不开以下人员的贡献: Anirudh Janga, Josh Cartmell, Arminé Iradian, Anupama Jasthi, Matt Jennings, Zack Weeden, John Long, Issac Gerges, Andrew MacDonald, Vani Anantha 和 Dave Harrington

有兴趣承担有趣的项目、让人们的日常工作更轻松,或者只是构建一些非常酷的表单吗?我们正在招聘!

探索机会

#ci-cd #developer-experience #developer-productivity #devops #frontend #testing

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