Chapter 12

CI の高速化における検討

tetter / Tetta Maeda
tetter / Tetta Maeda
2023.08.26に更新

🤔 Rust の CI における悩み

E2E テストを何度も動作させていると、Rust のビルドが長いことが気になるかもしれない。今回はあまり深くは追求しないが、いくつかの方法によってビルド時間を短縮することで CI の高速化を検討することができる。

🤔 インストール内容の削減

Rust のクレートには、何も指定せずにインストールすると全ての機能が含まれた状態でインストールされてしまうものがある。
features を適切に指定したり、必要最小限のクレートを使用するなど工夫すべきである。

🤔 crate.io index 更新の短縮

ビルド実行のたびに Updating crates.io index... と表示され、場合によっては数十秒の処理が発生されることがある。Cargo.toml へ以下のように記載をすることで、多少高速化できる。

Cargo.toml
...

[registries.crates-io]
protocol = "sparse"

https://blog.rust-lang.org/2023/03/09/Rust-1.68.0.html#cargos-sparse-protocol

上記オプションを指定すると、実行が少しだけ早くなる。なお、使用している cargo のバージョンが 1.70.0 以上であればデフォルトでこのオプションが有効になっているようなので、今回のチュートリアルに沿っていればこれを指定する必要はないだろう。

実際は上記のオプションを指定してもインデックスの更新は発生する。この更新自体を発生させないようにするには -Z no-index-update フラグを指定する必要がある。
こちらのフラグを設定したい場合は nightly を有効にする必要がある。以下のコマンドにより nightly を有効にできる。

rust-dev
$ rustup install nightly

インデックスの更新をスキップしてテストを行うコマンドは以下のとおりである。

rust-dev
$ cargo +nightly test -Z no-index-update

nightly で活用できるコマンドは こちら で確認できる。

なお、生成したばかりのコンテナで上記を実行してみたところ、以下のように chrono を発見できずエラーになってしまった。

error: no matching package named `chrono` found
location searched: registry `crates-io`
required by package `webapi_mvp v0.1.0 (/usr/src/myapp)`

ほとんどのクレートでエラーになることが想定されるため、クレートを全く利用していないパッケージを利用する場合か、一度インデックスの更新を実施したことがあるパッケージで使用する場合に採用するのが良いと思われる。

🤔 CI キャッシングの適用

Rust では、あまり変更のない依存関係をキャッシュするのが有効な手段となりうる。最も簡単に適用するのであれば、target ディレクトリ全体をキャッシュすることもできるのだが、target は非常に巨大であり、頻繁に変更されるのであまり効率が良くない。Cargo はデフォルトでは target のどの部分が依存関係なのか明確になっていないため、クリーンアップするためのコード を書く必要がある。

また、もしも GitHub actions を利用する場合、Swatinem/rust-cache を利用することができる。

上記は以下のサイトから引用しているが、他にも CI の高速化に有用な情報がいくつかあるため、本気で高速化に取り組みたい人はチェックしておくことをおすすめする。
https://matklad.github.io/2021/09/04/fast-rust-builds.html#CI-Caching