首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

通过替换 actions/setup-go 来扩展 Golang CI

摘要

We've found a new way to speed up parallel Golang continuous integration workflows by taking advantage of the Golang build cache. Replacing GitHub's official actions/setup-go action with a drop-in equ...

the our and you for new test can jobs speed
2026-09-17 1 阅读 约6分钟阅读 peterldowns
分享:
字号:
我们找到了一种利用 Golang 构建缓存来加速并行 Golang 持续集成工作流程的新方法。将 GitHub 的官方 actions/setup-go 操作替换为等效的直接操作,将我们的测试作业运行时间缩短了 69%。我们正在开源 cloudx-io/setup-go(在新选项卡中打开),因此您也可以这样做。 GitHub 的官方 actions/setup-go 步骤使并行作业相互干扰性能,并且不断加载过时的缓存值。在我们的 monorepo 中进行回测,常见的情况是几个并行的 Golang 测试作业(一个用于 lint,一个用于测试,一个用于构建),表明默认操作所做的 86% 的工作是完全不必要的。如果您管理一个中等复杂的 Go 项目,您可以期待类似的性能改进;请参阅我们的 CI 测量方法或亲自尝试一下。我们关心快速 CI 我们已经推出了许多新产品和功能,而且我们的速度实际上随着时间的推移而不断加快。这并非偶然——我们大力投资于实现这一目标所需的工具和流程。每个“软件工厂”的核心都是测试套件和持续集成 (CI) 工作流程,以确保代码更改不会在生产中中断。如果我们的测试在每次更改时都能可靠、快速地运行,我们就可以以惊人的速度进行构建,而不必担心给客户造成破坏。这对我们来说很重要,因此我们衡量并投资于 CI 工作的速度。如果您将代码推送到 CloudX 存储库,我们的目标是您在 90 秒内获得关于其可接受性的明确答案 - 是否可以构建、测试是否通过以及是否遵守我们的 linter 规则。可以通过多种方式实现速度,但归根结底,如果你想让事情变得更快,你就必须改进算法。我们已经在使用 Warp Build(在新选项卡中打开)在快速、经济高效的机器上运行 CI 作业。随着我们的测试套件随着产品表面积的扩展而扩展,我们意识到操作/设置并不能帮助我们取得成功。 actions/setup-go 如何在并行作业中失败 GitHub 的 actions/setup-go(在新选项卡中打开)是 GitHub 鼓励在 GitHub Actions 中安装和运行 Go 的方法。它内部使用 actions/cache 来保存和恢复本地 Go 模块缓存并构建缓存目录。原则上,这应该使从一个作业运行中下载的模块源代码和构建/测试工件可用于存储库中的所有后续作业运行。这是默认的 actions/setup-go 缓存键构造: 不幸的是,这个缓存键不完整:在积极开发的典型产品中,只有极少数的代码更改会修改目标操作系统、架构、Go 版本或 go.mod 文件。作业第一次计算此哈希键时,会将最终缓存状态保存到 GitHub 缓存服务。在下一次更改修改这些关键元素之一之前,每次 CI 运行都将加载第一个值。当您更改应用程序时,第一次运行中恢复的 go build 模块存档会减弱 - 每个后续构建都会从头开始执行更多工作。恢复的 go test 输出也会过时,因此每个后续作业都会重新运行更多测试。 CI 会降级,直到您更新 go.mod !此外,运行 actions/setup-go 的多个并行作业会竞相将不同的本地缓存状态写入 GitHub 缓存服务,这是不同的,因为运行器上的最终 Go 缓存状态取决于源代码和运行的命令。例如,您可以并行运行单独的 lint 和测试作业:两个作业解析相同的默认缓存键,然后竞相写入其值。假设 lint 作业首先完成:它保存一个值,但没有更新的测试缓存状态。后续测试作业将继续使用该过时的值,直到缓存键发生更改,因此无需重新运行测试。 Linting、构建和测试代码库是记忆化的理想选择:它们的输出(分别是 linter 消息、构建的二进制文件和测试结果)应该是源代码的纯函数。只要输入没有改变,您就可以存储输出并重用它们,而不是重新计算它们。标准 Go 工具链的几个部分将其输出保存到文件系统,并检查它们是否可以重用现有输出,而不是从头开始重新计算新输出: 缓存 控制环境变量 默认 Linux 位置 模块缓存 GOMODCACHE $GOPATH/pkg/mod 构建缓存 GOCACHE ~/.cache/go-build 测试缓存 GOCACHE ~/.cache/go-build Go 的模块缓存节省了下载模块依赖项的源代码所花费的时间,您可以使用 go mod download 显式触发它,但也可以使用 go mod download 显式触发它。隐含地使用 go build 。这里没有什么神秘的,只是由 go.mod 中的包标识符组织的源代码:当您更改 go.mod 时,您会触发新的下载,例如添加新的依赖项或升级现有的依赖项。 Go的构建缓存和测试缓存实际上都位于GOCACHE目录中,并且共享一个通用的str
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱