本节介绍了 Gradle 构建缓存的不同使用案例,从仅本地开发到跨大型团队缓存任务输出。
使用本地缓存加速开发者构建
即使仅由单个开发者使用,构建缓存也非常有用。Gradle 的增量构建功能有助于避免重复工作,但一旦您重新执行任务,任何先前的结果都会被遗忘。当您来回切换分支时,即使您正在构建以前已经构建过的东西,本地结果也会一次又一次地重建。构建缓存会记住先前的构建结果,并大大减少了在本地已经构建过的情况下重新构建的需求。这也可以扩展到重建不同的提交,例如运行git bisect
时。
本地缓存也适用于处理具有多个变体的项目,例如 Android 项目。每个变体都关联了许多任务,其中一些任务变体维度尽管名称不同,但最终可能会产生相同的输出。启用本地缓存后,当适用时,任务变体之间会自动进行重用。
在 CI 构建之间共享结果
构建缓存不仅可以及时回溯,还可以弥合计算机之间的物理距离,允许一台机器生成的结果被另一台机器重用。在团队中引入构建缓存的典型第一步是仅在作为持续集成一部分运行的构建中启用它。使用共享 HTTP 构建缓存后端(例如Develocity 提供的)可以显著减少 CI 代理需要完成的工作。这转化为开发者更快的反馈,以及更少的 CI 资源花费。更快的构建也意味着每个构建中包含的提交更少,这使得调试问题更高效。
从 CI 上的构建缓存开始是一个很好的第一步,因为 CI 代理上的环境通常比开发者机器更稳定和可预测。这有助于识别构建中可能影响可缓存性的任何问题。
如果您受到有关向客户交付的工件的审计要求的约束,您可能需要为某些构建禁用构建缓存。Develocity 可以帮助您在所有构建中仍然使用构建缓存的同时满足这些要求。它允许您通过构建扫描轻松查明哪个构建产生了来自构建缓存的工件。

通过重用 CI 结果加速开发者构建
当多个开发者在同一个项目上工作时,他们不仅需要构建自己的更改:每当他们从版本控制中拉取时,他们最终还需要构建彼此的更改。每当开发者处理与拉取更改无关的内容时,他们可以安全地重用 CI 上已生成的结果。例如,您正在处理模块“A”,并且您拉取了模块“B”的一些更改(不依赖于您的模块)。如果这些更改已在 CI 中构建,您可以从缓存下载模块“B”的任务输出,而不是在本地生成它们。这种情况的典型用例是开发者开始他们的一天,从版本控制中拉取所有更改,然后运行他们的第一次构建。
更改也无需完全独立;我们将在关于不同规范化形式的部分中介绍在涉及依赖项时重用结果的策略。
将远程结果与本地缓存结合
您可以同时利用本地缓存和远程缓存以实现复合效果。从 CI 填充的远程缓存加载结果有助于避免因其他开发人员的更改而需要进行的工作,而本地缓存可以加速分支切换和执行git bisect
。在 CI 机器上,本地缓存可以充当远程缓存的镜像,显著减少网络使用。
在开发者之间共享结果
允许开发者将其结果上传到共享缓存是可能的,但不推荐。开发者可以在任务执行期间更改任务输入或输出。他们可能会无意中且未察觉地这样做,例如在构建运行时在 IDE 中进行更改。目前,Gradle 没有很好的方法来防止这些更改,一旦任务完成,它只会缓存输出目录中的任何内容。这再次可能导致损坏的结果被上传到共享缓存。当 Gradle 添加了防止无意中修改任务输入和输出的必要保护措施时,此建议可能会更改。
如果您想共享增量构建(即非干净构建)的任务输出,您必须确保所有可缓存任务都已正确配置和实现以处理陈旧输出。例如,有些注解处理器不会清理相应类/资源目录中的陈旧文件。缓存是一个很好的强制函数,可以解决这些问题,这也会使您的增量构建更加可靠。同时,在您确信增量构建行为完美无缺之前,只使用干净构建将内容上传到缓存。 |