构建 CI

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

¥Turborepo speeds up builds, lints, tests, and any other tasks that you need to do in your Continuous Integration pipelines. Through parallelization and Remote Caching, Turborepo makes your CI dramatically faster.

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

¥For examples of how to connect your CI vendor to Remote Cache and run tasks, visit our CI guides.

启用远程缓存

¥Enabling Remote Caching

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

¥To enable Remote Caching for your CI, setup the environment variables for Turborepo to access your Remote Cache.

环境变量描述
TURBO_TOKEN用于访问远程缓存的 Bearer 令牌
TURBO_TEAM与你的仓库关联的账户名。使用 Vercel Remote Cache 时,此变量设置为 你团队的 slug

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

¥When you run tasks through turbo, your CI will be able to hit cache, speeding up your pipelines.

Remote Cache hosting

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

¥Vercel's built-in CI/CD is automatically connected to your managed Vercel Remote Cache with zero configuration. To retrieve a token for connecting your other CI vendors to Vercel Remote Cache, visit the Vercel Remote Cache documentation.

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

¥For self-hosted Remote Cache options, visit Turborepo's Remote Cache documentation.

正在运行任务 CI

¥Running tasks in CI

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

¥By installing turbo globally onto your development and CI machines, you can use one mental model to run your entire repository, from development to ship. The tasks that you've registered in your turbo.json will work exactly the same in CI.

  • 更多有关如何设置任务的信息,请访问 配置任务 页面。

    ¥For more information on how to set up tasks, visit the Configuring Tasks page.

  • 有关在 CI 中运行任务的示例,请访问我们的 CI 指南

    ¥For examples of running tasks in CI, visit our CI guides.

按入口点过滤

¥Filtering for entry points

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

¥You can filter your tasks using the --filter flag exactly the same as when you're working with turbo locally. Filtering by packages, directories, and Git history are all supported in CI.

Using Git history in CI

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

¥Filtering using source control changes is only possible when history is available on the machine. If you are using shallow clones, history will not be available.

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

¥You can also use the --affected flag to only run tasks in packages that have changes.

Docker

Docker 是许多部署流水线的重要组成部分。Turborepo 的 prune 子命令 可帮助你从镜像中删除不必要的依赖和代码,从而交付轻量级镜像。

¥Docker is an important part of many deployment pipelines. Turborepo's prune subcommand helps you ship lightweight images by removing unnecessary dependencies and code from your images.

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

¥For more on how to deploy from a Turborepo with Docker, visit the dedicated Docker guide.

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

¥Skipping tasks and other unnecessary work

仅运行受影响的任务

¥Running only affected tasks

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

¥You can use the --affected flag to only run tasks that have changes.

Terminal
turbo run build --affected

你需要在以下情况下使用此标志:

¥You'll want to use this flag in situations like:

  • 你正在 monorepo 中的包之间运行许多任务,并且只想在代码发生更改的包中运行这些任务。

    ¥You're running many tasks across packages in your monorepo, and only want to run those tasks in packages with code changes.

  • 你没有使用远程缓存,但仍希望在 CI 中尽可能少地工作。

    ¥You’re not using a Remote Cache, but still want to do as little work as possible in CI.

  • 你正在使用远程缓存,并且你的代码库很大。通过最小化从缓存中恢复的任务量,可以减少通过网络发送的数据量,从而加快缓存恢复速度。

    ¥You are using a Remote Cache, and you’re in a large repository. By minimizing the amount of tasks that will be restored from cache, there will be less data to send across the network, resulting in faster cache restoration.

  • 你已经在使用 高级过滤技术turbo-ignore 来创建与 --affected 相同或类似的行为。你很可能有机会使用此新标志简化脚本编写。

    ¥You’re already using advanced filtering techniques or turbo-ignore to create the same or similar behavior as --affected. You likely have the opportunity to simplify your scripting using this new flag.

    • --affected 可以比定制过滤更优雅地处理浅克隆,因为它会回退到运行所有任务。

      ¥--affected will can handle shallow clones more gracefully than bespoke filtering because it falls back to running all tasks.

在 GitHub Actions 中使用 --affected

¥Using --affected in GitHub Actions

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

¥CI/CD pipelines are a perfect place to use --affected. With --affected, Turborepo can automatically detect that you're running in GitHub Actions by inspecting environment variables set by GitHub, like GITHUB_BASE_REF.

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

¥In the context of a PR, this means that Turborepo can determine which packages have changed between the PR's base branch and the PR's head branch. This allows you to run tasks only for the packages that are affected by the changes in the PR.

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

¥While GITHUB_BASE_REF works well in pull_request and pull_request_target events, it is not available during regular push events. In those cases, we use GITHUB_EVENT_PATH to determine the base branch to compare your commit to. In force pushes and pushing branch with no additional commits, we compare to the parent of the first commit on the branch.

使用 turbo-ignore

¥Using turbo-ignore

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

¥As your codebase and CI grow, you may start to look for more ways to get even faster. While hitting cache is useful, you also may be able to skip work entirely. Using turbo-ignore, you can skip lengthy container preparation steps like dependency installation that will end up resulting in a cache hit, anyway.

检出代码库

¥Checkout the repository

首先克隆你的代码库。请注意,你需要一个具有你计划使用的克隆深度历史记录的克隆,以便进行比较。

¥Start by cloning your repository. Note that a clone with history to the cloning depth you plan on using is necessary for comparisons.

Good to know: 

默认情况下,turbo-ignore 使用父提交。要进行更深入的自定义,请参阅 turbo-ignore 参考

¥By default, turbo-ignore uses the parent commit. To customize for more depth, see the turbo-ignore reference.

为包和任务运行 turbo-ignore

¥Run turbo-ignore for the package and task

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

¥By default, turbo-ignore will use the build task in the current working directory.

  • 要检查其他任务的更改,请使用 --task 标志。

    ¥To check for changes to a different task, use the --task flag.

  • 要检查特定包及其依赖的更改,请添加包名称作为参数。

    ¥To check for changes for a specific package and its dependencies, add the package's name as an argument.

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

¥Check for changes for the build task for the web package and its dependencies by adding the web package as an argument:

Terminal
npx turbo-ignore web

处理结果

¥Handle the result

如果在包或其 内部依赖 中检测到更改,turbo 将退出并返回 1 状态码。如果没有检测到任何更改,它将退出并运行 0

¥If changes are detected in the package or its Internal Dependencies, turbo will exit with a 1 status code. If no changes are detected, it will exit with 0.

使用此状态代码,你可以选择 CI 管道的其余部分应执行的操作。例如,1 退出代码可能意味着你应该继续安装依赖并运行任务。

¥Using this status code, you can choose what the rest of your CI pipeline should do. For instance, a 1 exit code likely means that you should move forward with installing dependencies and running tasks.

有关更高级的用例,请参阅 turbo-ignore 参考

¥For more advanced use cases, see the turbo-ignore reference.

最佳实践

¥Best practices

依赖缓存

¥Rely on caching

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

¥Turborepo's caching abilities allow you to create fast CI pipelines with minimal complexity. Through Remote Caching and using the --filter flag to target packages for builds, Turborepo will handle change detection for large monorepos with little overhead.

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

¥For example, your CI could run these two commands to quickly handle quality checks and build your target application:

  • turbo run lint check-types test:对整个仓库运行质量检查。任何未更改的包都将进入缓存。

    ¥turbo run lint check-types test: Run quality checks for your entire repository. Any packages that haven't changed will hit cache.

  • turbo build --filter=web:使用你在 turbo.json 中注册的 build 任务构建 web 包。如果 web 包或其依赖没有更改,构建也会命中缓存。

    ¥turbo build --filter=web: Build the web package using the build task you've registered in turbo.json. If the web package or its dependencies haven't changed, the build will also hit cache.

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

¥As your codebase scales, you may find more specific opportunities to optimize your CI - but relying on caching is a great place to start.

CI 中的全局 turbo

¥Global turbo in CI

在 CI 工作流中使用全局 turbo 非常方便,让你可以轻松运行特定于 CI 的命令并利用 自动工作区作用域

¥Using global turbo is convenient in CI workflows, allowing you to easily run commands specific to your CI and take advantage of Automatic Workspace Scoping.

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

¥However, in some cases, you may be running turbo commands or scripts that use turbo before installing packages with your package manager. One example of this is using turbo prune to create a Docker image. In this situation, global turbo will not be able to use the version from package.json because the binary for that version hasn't been installed yet.

因此,我们建议你将 CI 中 turbo 的全局安装固定到 package.json 的主版本,因为重大更改不会在主版本中引入。你还可以选择通过固定确切版本来提高稳定性,以维护负担为代价来接收补丁版本中的错误修复。

¥For this reason, we encourage you to pin your global installation of turbo in CI to the major version in package.json since breaking changes will not be introduced within a major version. You could additionally opt for added stability by pinning an exact version, trading off for maintenance burden to receive bug fixes in patch releases.

在 CI 中使用 turbo run

¥Use turbo run in CI

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

¥turbo run is the most common command you will use when working in your Turborepo so it is aliased to turbo for convenience. While this is great for working locally, there are other subcommands for turbo like turbo prune and turbo generate.

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

¥We're always working to make turbo better so we may add more subcommands in the future. For this reason, you can prevent naming collisions by using turbo run in your CI.

例如,如果你的 CI 管道中有一个 turbo deploy 命令,它可能与直接内置于 turbo CLI 中的潜在 deploy 子命令冲突。为避免这种情况,请在你的 CI 管道中使用 turbo run deploy

¥As an example, if you have a turbo deploy command in your CI pipelines, it may conflict with a potential deploy subcommand built directly into the turbo CLI. To avoid this, use turbo run deploy in your CI pipeline instead.

故障排除

¥Troubleshooting

访问缓存导致构建失败

¥Hitting cache results in broken builds

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

¥If your task is passing when you miss cache but failing when you hit cache, you likely haven't configured the outputs key for your task correctly.

使用错误的环境变量进行部署

¥Deployment using the wrong environment variables

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

¥If you haven't defined the env or globalEnv keys for your task, Turborepo will not be able to use them when creating hashes. This means your task can hit cache despite being in a different environment.

检查 envglobalEnv 键的配置。

¥Check your configuration for the env and globalEnv keys.

后续步骤

¥Next steps

现在,你已拥有使用 Turborepo 交付应用所需的一切。要了解更多关于具体用例的信息,请参阅 查看指南深入了解核心概念

¥You now have everything you need to ship applications with Turborepo. To learn more about specific use cases, check the Guides or dive deeper into core concepts.