# Rust CI/CD 实践

Original: <https://lifelonglearn.ing/rust-ci-cd-best-practices>

Author: [奶爸](https://lifelonglearn.ing/users/3b04650c-8231-499b-8ef0-381fc4d7efb0)

Published: 2021-10-18T13:14:36Z

Updated: 2026-09-27T06:57:43Z

Version: 1

使用 Rust 也有一段时间了，大部分应用是在公司的后端 API 上面，有两个服务一个源自ZenGo的Rust门限签名的苦，都有深度参与。门限签名的初版就是出自奶爸之手，从 gotham-city 这个库里面剥离出来的一套流程。

我司一直都是使用GitHub，GitHub 没有将组织免费时我司使用的是奶爸做的一个 [GitHub 个人账户管理工具](https://lifelonglearn.ing/r/go?url=aHR0cHM6Ly9naXRodWIuY29tL25haWJhaHEvcG9vcnNxdWFk)，基本上管理团队的一些必备功能都有，人员管理、外部贡献者管理、仓库创建删除重命名等。然后 GitHub Team 免费之后我就将仓库 Archive 了，没啥价值了嘛，然后主导将账户转为了组织账户。

再后面 GitHub 推出了 Actions、Package Registry 服务，在这些服务出来之前，我司使用的是奶爸做的一个 [NoCD 持续交付工具](https://lifelonglearn.ing/r/go?url=aHR0cHM6Ly9naXRodWIuY29tL25haWJhL25vY2Q=) 来实现内部部署流程自动化的，同样在 GitHub 出了 Actions 之后奶爸也不怎么维护 NoCD 了，当时在团队内部奶爸做的这两个工具还是很好用的，但是至于为什么没有 Archive 掉这个仓库，是因为在现阶段，编译缓存、内网部署等特殊需求 NoCD 还是比较适用的，还有一些价值，所以就不 Archive 了。

好，说回正题吧，Rust 的 CI/CD 的最佳实践。

## Rust CI/CD

首先的话就是利用上 GitHub Actions，使用 Actions 来打包发布 Rust 项目。

然后用起来之后我们发现 Rust 的编译耗时比较长，该怎么优化呢，所以就加入了 **sccache** 来进行构建缓存。

然后整个流程的时间就大大缩减了。

## sccache 的问题

在使用过程中我们发现从某一天开始这个构建时间突然变长了，因为平时工作安排比较满没有时间去特意看一下是什么问题，所以一只在搁置。

但是这个问题一只困扰着奶爸，所以在今天奶爸决心将这个问题解决掉，因为在 Actions 里面打印了 sccache stats，在构建 Docker 镜像之前有一个前置的测试流程，测试流程跟 Docker 镜像构建流程都是用了 Actions Cache 这个东西。

但是发现在 测试流程 里面，sccache 是工作的 99% 的编译请求都是 hit，只有一个两个是miss，而在测试通过之后的构建流程，hit 是 0 ，miss 100%。这就很奇怪了，两个 workflow 的代码是一模一样的。

经过翻来覆去的思考，终于发现了问题所在，我们测试 workflow 里面的编译是 debug 版本，然后 sccache 根据 `Cargo.lock` 缓存的是一个 debug 编译过程，然后我们 Docker 镜像构建又是 release，就导致 sccache 无法使用缓存的编译过程。

然后 workflow 执行成功之后，post hook 又不会更新缓存，因为缓存的key，是一样的 `Cargo.lock` 内容没有变化，就导致我们在上了前置测试流程之后，每次 Docker 构建流程都全量编译了，耗费了大量时间。

解决了 sccache，Rust 交付起来就美滋滋了，在这放一个 [Rust CI/CD 的示例项目](https://lifelonglearn.ing/r/go?url=aHR0cHM6Ly9naXRodWIuY29tL25haWJhL3R3aXR0ZXIydGVsZWdyYW0=) 供各位参考。

## 影响 sccache 命中的因素

1. 主要还是 `Cargo.lock`，剩下就是可能 `Cargo.lock` 文件没有变化，但是会导致构建过程有变化的因素
2. 构建类型 debug/release
3. rustc 版本
