Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@nacam403

React NativeアプリをBitriseでビルドする際のキャッシュ設定は、難しく考えなくても大丈夫

More than 1 year has passed since last update.

はじめに

React NativeアプリのCIに使えるサービスとして、有力なものの一つがBitriseです。
BitriseでCIを行う際にキャッシュを利用すると、2回目以降のビルド時間を短縮できます。
では実際、キャッシュの設定をどうすればよいかを考えていきます。

Bitriseでキャッシュを利用するには

CIによるビルドの一般論として、以下の様にキャッシュを利用することで、2回目以降のビルド時間が短縮できます。

ビルドの流れ

  1. Gitリポジトリをクローンする。
  2. (あれば)前回のビルドの際に保存しておいたキャッシュを取得する。
  3. 各種の依存性をインストールする。もしもキャッシュを取得できていたら、ここの所要時間を短縮できる。
  4. ビルドする。
  5. ビルド成果物を所定の場所に格納する。
  6. 特定のファイルやディレクトリをキャッシュとして保存しておく。

Bitriseにも、キャッシュの取得(Pull)や保存(Push)を行うためのステップが用意されています。
image.png
image.png

Pullは「もしキャッシュがあれば、それを取ってくる」を行うだけですので、さほど細かい設定はありません。
一方、Pushは「何をキャッシュするか」や「どういう時にはキャッシュを更新するか」などを設定する必要があり、この設定が時間短縮効果に影響してきます。

Pushの設定項目Cache pathsにnode_modulesを指定する

Pushには色々な設定項目があるのですが、何をキャッシュするかを指定するCache pathsがもちろん肝心です。初期値として設定されている$BITRISE_CACHE_DIRに加えて、キャッシュしたいパスを書き足していきます。

image.png

React Nativeアプリのプロジェクトの場合、キャッシュ対象としてまず思いつくのはnode_modulesディレクトリでしょう。
ここでの留意点として、Cache pathsには矢印つきの記法があることに注目してください。Cache pathsのあたりを押すと表示される詳細説明にて触れられています。「このファイルが変わった時には、キャッシュのこの部分を必ず更新してね」というファイルを指定することもできるのです。

image.png

node_modulesに対応するファイルはというと、package-lock.jsonになるでしょう(yarnを使っているならyarn.lock)。そこでCache pathsには以下の様に書き足します。

node_modules -> package-lock.json

node_modulesをGitリポジトリのルート直下に置いていない場合は、パスも指定すればOKです。

path/to/node_modules -> path/to/package-lock.json

node_modules以外のキャッシュはどうするか

無事にnode_modulesをキャッシュする設定ができました。これで、2回目以降のnpm install(またはyarn install)にかかる時間がかなり短縮されます。正しく設定できているかどうか、試しにビルドして確認しておきましょう。

node_modulesの他にも、iOSやAndroidに特有の依存性などもキャッシュしたいところです。「でも、そういうネイティブな部分はあんまり詳しくないし、どんなパスを設定したらよいのやら・・・」という人も多いのではないでしょうか。

自分で設定しなくても、良きにキャッシュしてくれる仕掛けが実はあった

実は、Pushの設定項目にはCache paths collected runtimeというものも存在します。設定値は変更不可です。ここの指定と、先ほど自分で指定したCache pathsを合わせた結果が、実際のキャッシュ対象となります。

image.png

ではこちらで指定されている$BITRISE_CACHE_INCLUDE_PATHSという環境変数の値は何なのかというと、Pushの手前にあるステップに応じて自動的にセットされているのです。

例えば、Android Buildというステップがあります。
image.png
これをデフォルト設定で使っているだけで、以下の様な値が$BITRISE_CACHE_INCLUDE_PATHSの末尾に追加されます。

/Users/vagrant/.gradle -> /Users/vagrant/git/modules/SampleApp/android/gradle.deps
/Users/vagrant/.kotlin -> /Users/vagrant/git/modules/SampleApp/android/gradle.deps
/Users/vagrant/.m2 -> /Users/vagrant/git/modules/SampleApp/android/gradle.deps

Android Buildの他にも、いくつかのステップには同様の処理が仕込まれています。BitriseのステップはGitHubに公開されていますので、ソースコードを辿っていけば、$BITRISE_CACHE_INCLUDE_PATHSに値を指定する処理を確認することもできます。

ともあれ、(任意のスクリプトを実行する汎用のステップではなく)Bitriseに用意されたステップを用いてビルドしていれば、良きにはからってキャッシュしてくれるということです。Bitriseのドキュメント(下記のURL)を見ても、「Cocoapods installやAndroid Buildといったステップと、Cache:PullやCache:Pushを使ってね」という程度の説明しかありません。

https://devcenter.bitrise.io/caching/caching-cocoapods/
https://devcenter.bitrise.io/caching/caching-gradle/

Bitriseはモバイルアプリに特化したCIサービスですから、iOS/Androidアプリをビルドする際にほぼ誰もがキャッシュしたいパスは、細かい設定なしにキャッシュするように設計されているのでしょう。

ここまでのまとめ

React Nativeアプリの場合、node_modulesをキャッシュするように指定しておけばとりあえずOKです。
その際、package-lock.json(またはyarn.lock)が更新されたらキャッシュも更新されるように、矢印つきの記法にしておきましょう。

もっと最適化したかったら

Pushの設定項目の一つであるDebug modeをtrueにしておくと、以下の様な詳細がビルドのログに出力されます。キャッシュ設定を突き詰める際に役立ちます。

  • キャッシュ対象のパス
  • キャッシュ対象のパスに含まれていても、例外的に無視したいパス
  • 前回のビルド後にキャッシュしたものに、今回のビルド後に変更が生じたかどうか(つまりキャッシュの更新が必要かどうか)
  • Pushの各工程の所要時間

以下の図は、私がビルドした際のログの抜粋です。
Androidアプリのビルドの度に生じるログファイル(ファイル名が毎回違う)のために、File changes foundと判定されてしまっています。例外的に無視したいパスの設定に改善の余地があるということでしょう(*.logを無視する設定は入っていたものの、その設定が*.out.logには効かなかったらしいです)。
File changes foundになったために、新しいキャッシュファイルを生成したり、それをアップロードして保存する処理が走ってしまい、15秒くらい損をしています。

image.png

こうした現象を潰しながらキャッシュ設定を最適化していけば、ビルド時間を更に短縮できるかもしれません。下記などを天秤にかけて、最適化するかどうかを判断するとよいでしょう。

  • ビルドの頻度
  • ビルド全体の時間
  • 短縮できそうな時間
  • キャッシュ設定を試行錯誤するのに必要な時間(≒ ビルド全体の時間 x N回)

頑張って最適化したとしても、今後、自分のプロジェクトが使っているライブラリの変更や、Bitriseのステップの変更などの拍子に状況が変わるかもしれません。「別にこれくらいはいいや」と、ほどほどに打ち切るのも十分ありです。

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
nacam403
CureAppで色々やっているエンジニアリングマネージャーです。
cureapp
医学的エビデンスに基づいた医療機器プログラム『治療アプリ』を開発しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?