构建 CI

Turborepo 可以加速构建、代码检查、测试以及你在持续集成流水线中需要执行的任何其他任务。通过并行化和远程缓存,Turborepo 可以显著加快你的 CI 速度。

要了解如何将你的 CI 供应商连接到远程缓存并运行任务的示例,请访问我们的 CI 指南

启用远程缓存

要为你的 CI 启用远程缓存,需要设置环境变量以让 Turborepo 访问你的远程缓存。

环境变量描述
TURBO_TOKEN访问远程缓存的 Bearer 令牌
TURBO_TEAM与你的仓库关联的账户名称。当使用 Vercel 远程缓存时,这是你的团队 slug

当你通过 turbo 运行任务时,你的 CI 将能够命中缓存,加快你的流水线速度。

远程缓存托管

Vercel 的内置 CI/CD 会自动连接到你管理的 Vercel 远程缓存,无需配置。要获取用于将其他 CI 供应商连接到 Vercel 远程缓存的令牌,请访问 Vercel 远程缓存文档

对于自托管远程缓存选项,请访问 Turborepo 的远程缓存文档

在 CI 中运行任务

通过全局安装 turbo 到你的开发和 CI 机器上,你可以使用一个思维模型来运行整个仓库,从开发到发布。你在 turbo.json 中注册的任务在 CI 中的工作方式将完全相同。

  • 有关如何设置任务的更多信息,请访问配置任务页面。
  • 有关在 CI 中运行任务的示例,请访问我们的 CI 指南

过滤入口点

你可以使用--filter 标志来过滤任务,就像在本地使用 turbo 时一样。在 CI 中支持按包、目录和 Git 历史进行过滤。

在 CI 中使用 Git 历史

只有当机器上有历史记录时,才能使用源代码控制更改进行过滤。如果你使用浅克隆,历史记录将不可用。

你还可以使用--affected 标志来仅运行有更改的包中的任务。

Docker

Docker 是许多部署流水线的重要组成部分。Turborepo 的 prune 子命令通过移除不必要的依赖项和代码来帮助你发布轻量级镜像。

要了解更多关于如何使用 Docker 从 Turborepo 部署的信息,请访问专门的 Docker 指南

跳过任务和其他不必要的工作

仅运行受影响的任务

你可以使用 --affected 标志来仅运行有更改的任务。

Terminal
turbo run build --affected

在以下情况下你会想要使用这个标志:

  • 你在 monorepo 中的多个包之间运行许多任务,并且只想在有代码更改的包中运行这些任务。
  • 没有使用远程缓存,但仍想在 CI 中尽可能少做工作。
  • 正在使用远程缓存,并且你在一个大型仓库中。通过最小化将从缓存中恢复的任务数量,网络上传输的数据会更少,从而导致更快的缓存恢复。
  • 你已经在使用高级过滤技术turbo-ignore来创建与 --affected 相同或类似的行为。你可能有机会使用这个新标志来简化你的脚本。
    • --affected 可以比自定义过滤更优雅地处理浅克隆,因为它会退回到运行所有任务。

在 GitHub Actions 中使用 --affected

CI/CD 流水线是使用 --affected 的完美场所。使用 --affected,Turborepo 可以通过检查 GitHub 设置的环境变量(如 GITHUB_BASE_REF)自动检测到你正在 GitHub Actions 中运行。

在 PR 的上下文中,这意味着 Turborepo 可以确定在 PR 的基础分支和 PR 的头部分支之间哪些包发生了变化。这允许你只为 PR 中受更改影响的包运行任务。

虽然 GITHUB_BASE_REFpull_requestpull_request_target 事件中工作良好,但在常规推送事件期间它是不可用的。在这些情况下,我们使用 GITHUB_EVENT_PATH 来确定要与你的提交进行比较的基础分支。在强制推送和推送没有额外提交的分支时,我们会与分支上第一个提交的父提交进行比较。

使用 turbo-ignore

随着你的代码库和 CI 的增长,你可能会开始寻找更多方法来获得更快的速度。虽然命中缓存很有用,但你也可能可以完全跳过工作。使用 turbo-ignore,你可以跳过冗长的容器准备步骤,比如依赖项安装,这些步骤最终会导致缓存命中。

检出仓库

首先克隆你的仓库。注意,需要有克隆深度你计划使用的历史记录才能进行比较。

Good to know: 

默认情况下,turbo-ignore 使用父提交。要自定义更多深度,请参见 turbo-ignore 参考

为包和任务运行 turbo-ignore

默认情况下,turbo-ignore 将使用当前工作目录中的 build 任务。

  • 要检查不同任务的更改,请使用 --task 标志。
  • 要检查特定包及其依赖项的更改,请添加包的名称作为参数。

通过添加 web 包作为参数来检查 web 包及其依赖项的 build 任务的更改:

Terminal
npx turbo-ignore web

处理结果

如果在包或其 内部依赖项 中检测到更改,turbo 将以 1 状态码退出。如果未检测到更改,它将以 0 退出。

使用此状态码,你可以选择你的 CI 流水线的其余部分应该做什么。例如,1 退出码可能意味着你应该继续安装依赖项并运行任务。

对于更高级的用例,请参见 turbo-ignore 参考

最佳实践

依赖缓存

Turborepo 的缓存能力允许你以最小的复杂性创建快速的 CI 流水线。通过远程缓存和使用 --filter 标志来定位包进行构建,Turborepo 将以很小的开销处理大型 monorepos 的变更检测。

例如,你的 CI 可以运行这两个命令来快速处理质量检查并构建你的目标应用程序:

  • turbo run lint check-types test:为你的整个仓库运行质量检查。任何没有更改的包都会命中缓存。
  • turbo build --filter=web:使用你在 turbo.json 中注册的 build 任务构建 web 包。如果 web 包或其依赖项没有更改,构建也会命中缓存。

随着你的代码库规模的扩大,你可能会发现更多具体的机会来优化你的 CI - 但依赖缓存是一个很好的起点。

CI 中的全局 turbo

在 CI 工作流中使用全局 turbo 很方便,它允许你轻松运行特定于你的 CI 的命令并利用自动工作空间作用域

然而,在某些情况下,你可能在使用包管理器安装包之前运行 turbo 命令或使用 turbo 的脚本。一个例子是使用 turbo prune 创建 Docker 镜像。在这种情况下,全局 turbo 将无法使用来自 package.json 的版本,因为该版本的二进制文件还没有安装。

因此,我们建议你在 CI 中将全局安装的 turbo 固定到 package.json 中的主版本,因为在主版本内不会引入破坏性更改。你还可以选择通过固定确切版本来获得额外的稳定性,以权衡维护负担来接收补丁版本中的错误修复。

在 CI 中使用 turbo run

turbo run 是你在 Turborepo 中工作时最常用的命令,为了方便起见,它被别名为 turbo。虽然这对于本地工作很好,但 turbo 还有其他子命令,如 turbo pruneturbo generate

我们一直在努力使 turbo 变得更好,所以我们将来可能会添加更多子命令。因此,你可以通过在 CI 中使用 turbo run 来防止命名冲突。

例如,如果你在 CI 流水线中有一个 turbo deploy 命令,它可能会与直接内置到 turbo CLI 中的潜在 deploy 子命令发生冲突。为了避免这种情况,在你的 CI 流水线中使用 turbo run deploy 代替。

故障排除

命中缓存导致构建失败

如果你的任务在未命中缓存时通过但命中缓存时失败,你可能没有正确配置任务的 outputs

部署使用错误的环境变量

如果你没有为你的任务定义 envglobalEnv 键,Turborepo 将无法在创建哈希时使用它们。这意味着你的任务可能会在不同的环境中命中缓存。

检查你的配置中的 envglobalEnv 键。

下一步

你现在已经拥有使用 Turborepo 发布应用程序所需的一切。要了解更多关于特定用例的信息,请查看指南深入了解核心概念