はじめに
最近、React Nativeで作ったアプリをBitriseでビルドするのを試しています。
ワークフロー自体はBitrise側が連携するリポジトリをスキャンして雛形を用意してくれるので導入自体は簡単です。
ところが、Bitriseのビルドはプランごとにビルド時間の制限があります。無料のHobby tierだと10分ですし、$36/月のSolo Developerプランでも45分という制限があります。
これはつまりワークフローがその時間内に終わらないとビルドがタイムアウトしてしまうということですね。
さて、React NativeのアプリではiOSとAndroidの両方をビルドする感じでワークフローができあがります。で、僕の環境だとそれぞれ20分くらい。Solo Developerプランでやってたのですが、iOSとAndroidのビルド以外のReact Native自体の依存関係の解決なども含めるとSolo Developerの45分をオーバーするようになってしまいました。
とはいえより上位のプランであるOrg Standardは90分まで増えるものの$90/月です。これは流石に厳しい。というわけで悩んでたわけです。
bitriseでReact NativeなアプリをAndroidとiOSの両方でビルドできるようにはなったんだがワークフローの実行時間が長くなってしまっててしばしばタイムアウト。ソロデベロッパープランの45分ギリギリ。AndroidとiOSでワークフローわけたいけど同じブランチをトリガーに複数ワークフローは無理っぽい🥺
— Keisuke Nishitani (@Keisuke69) 2021年3月2日
で、親切な方々が解決方法を2パターン教えてくれたのでここでまとめておきます。
トリガーされたワークフロー内から呼び出す
今は1つのワークフローにAndroidとiOSのビルドが両方とも別々のStepとして存在している状態です。
これをAndroidとiOSでそれぞれわけたワークフローを用意するのです。トリガーで呼び出すワークフローをどちらかに設定します。ここでは例えばiOSのワークフローを設定します。
その上でここで設定したワークフローにBitrise Start Build
というStepをワークフローの一番最初に追加します。そしてそこで別のワークフロー、ここではAndroidのワークフローをトリガーするように設定します。
ワークフローを呼び出すのに必要なBitrise Access Token
は事前にAccount Settings
のSecurity
で作成しておいてください。
はい、これだけで特定ブランチへのプッシュが行われると指定したワークフローがトリガーされて、そのワークフローからもう一方のワークフローをトリガーすることになるので、それぞれ20分ちょっとで終わることとなりタイムアウトしなくなります。
なお、このプランでは同時実行はあくまでも1なので自動で呼び出してはくれるものの、呼び出されたほうはOn Hold
ということで待ちの状態になっています。なので、両方のビルドが終わる総時間が短くなるわけでないのでそこだけ注意。
Bitrise CLIで並列ビルド
これも教えてもらいました。具体的には以下のQiitaの記事で解説されています。
Bitrise で並列ビルド (iOS/Android) - Qiita
簡単に言うと先と同じようにAndroidとiOSの2つのワークフローを定義します。その上で先ほどのBitrise Start Build
からの呼び出しではなく、ワークフロー上でBitrise CLIを実行するスクリプトを定義して実行するステップを用意してそこからそれぞれのワークフローを呼び出す形です。
また、それらのワークフローを定義したbitrise.yml
をリポジトリに含めておきます。
こんな感じです。
強いて難点があるとすると、先の方法とは異なり1つのワークフロー内でスクリプト実行としてそれぞれのワークフローを並列実行することになるのでワークフロー実行時の出力が混ざるとかでしょうか。
まとめ
というわけでタイムアウトしないようにするにはワークフロー1つあたりの実行時間を短くすればいいってことでAndroidとiOSのワークフローを別にしてそれぞれ実行する方法2パターンです。個人的には見た目のわかりやすさが気に入ったので最初の方法でやってます。
あと、実行時間そのものを短くできるようにするとよりいいですね。iOSだとFlipperを外すのもいいですよ。