构建 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 中的工作方式将完全相同。
过滤入口点
你可以使用--filter
标志来过滤任务,就像在本地使用 turbo
时一样。在 CI 中支持按包、目录和 Git 历史进行过滤。
在 CI 中使用 Git 历史
只有当机器上有历史记录时,才能使用源代码控制更改进行过滤。如果你使用浅克隆,历史记录将不可用。
你还可以使用--affected
标志来仅运行有更改的包中的任务。
Docker
Docker 是许多部署流水线的重要组成部分。Turborepo 的 prune
子命令通过移除不必要的依赖项和代码来帮助你发布轻量级镜像。
要了解更多关于如何使用 Docker 从 Turborepo 部署的信息,请访问专门的 Docker 指南。
跳过任务和其他不必要的工作
仅运行受影响的任务
你可以使用 --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_REF
在 pull_request
和 pull_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
任务的更改:
对于更高级的用例,请参见 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 prune
和 turbo generate
。
我们一直在努力使 turbo
变得更好,所以我们将来可能会添加更多子命令。因此,你可以通过在 CI 中使用 turbo run
来防止命名冲突。
例如,如果你在 CI 流水线中有一个 turbo deploy
命令,它可能会与直接内置到 turbo
CLI 中的潜在 deploy
子命令发生冲突。为了避免这种情况,在你的 CI 流水线中使用 turbo run deploy
代替。
故障排除
命中缓存导致构建失败
如果你的任务在未命中缓存时通过但命中缓存时失败,你可能没有正确配置任务的 outputs
键。
部署使用错误的环境变量
如果你没有为你的任务定义 env
或 globalEnv
键,Turborepo 将无法在创建哈希时使用它们。这意味着你的任务可能会在不同的环境中命中缓存。
检查你的配置中的 env
和 globalEnv
键。
下一步
你现在已经拥有使用 Turborepo 发布应用程序所需的一切。要了解更多关于特定用例的信息,请查看指南或深入了解核心概念。