こんにちは。ピクシブでiOS・Androidアプリ開発をしているkwzrです。 ピクシブでは2018年1月からモバイルアプリのCIをBitriseに切り替えて、約1年間運用してきました。この記事ではピクシブでのBitriseの使用状況を紹介していきます。
Bitriseとは
Bitriseはモバイル向けのCIサービスです。ネイティブのiOS、Androidはもちろん、XamarinやReact Native、Flutterなどクロスプラットフォームのプロジェクトにも対応しています。 ビルドの流れ(ワークフロー)やビルドトリガーをGUIで設定できたり、モバイル向けの機能が充実しています。
Bitrise導入以前
Bitriseを使う前は、macmini 3台を使ってJenkinsでCIを走らせていました。 その時の記事はこちら → Mac mini増殖中!iOSアプリのビルドをマスター・スレーブ化して時間を短縮する
macminiはモバイルアプリ開発者が管理していたものなので、セキュリティの関係上社外からアクセスできないようにしていました。そのため、リモートでCIの結果を見たりアプリをインストールするにはVPNにつなぐ必要があって面倒だったり、新しいXcodeが出るたびにインストールするのが面倒だったりしたため、CIサービスの導入を検討していました。
Bitriseを導入して
ピクシブのアプリはiOS・Android含めて13個ほど公開されており、Bitriseにも内製ライブラリなどを含めて21個登録されています。 全部のアプリが登録されているので、iOS・Androidアプリの開発を兼任しているエンジニアも複数のCIサービスを使わなくて済んで、楽という意見があります。
Jenkinsからの移行ですが、iOSの証明書やProvisioning Profileの扱いがしやすかったり、ワークフローをGUIで設定できるなど、モバイルアプリ向けに特化しているため、導入はスムーズにできました。
ピクシブの例
プロダクトによってワークフローやトリガーの設定の仕方は様々で、リポジトリに bitrise.yml
を入れてワークフローの差分管理をしているプロダクトもあります。しかし、多くのプロダクトではGUIでワークフローを管理していて、個人的にもGUIでワークフローを管理するのはアリだと思っています。
他プロダクトのワークフローがどうなっているか視覚的に参考にしやすいので、自然に各プロダクトのワークフローが良くなっていく実感があります。
Bitriseには過去のワークフローに戻せる差分管理機能が実装されているので、差分管理するためだけに bitrise.yml
をリポジトリに入れる必要はないと思います。
アプリの数が多く、各プロダクトが思い思いにビルドを走らせているため、1週間のビルド回数は約300回を超えます。 導入するプランに関してかなり悩みましたが、現在はOrg Standardプラン(最大6同時ビルド)を利用しています。 ハイスペックなマシンを利用できるEliteプランもありますが、トライアル(最大3同時ビルド)を試したところ、1回のビルドは最大5分ほど速くなるのですが、アプリのビルドは10〜20分以上掛かることが珍しくないため、3並列だと頻繁にビルドが詰まってホールドしてしまうことがありました。
担当するプロダクトのビルド時間が長いのはなんとかできますが、他のプロダクトのビルドを待っているとヘイトが溜まってしまうので、同時ビルド数を上げてホールドを減らすプランにする方が安価に効率を上げられると考えました。
プロダクトごとにBitriseのOrganizationを分けるのはどうか?という案もありましたが、退職者が出た場合など、アカウントの管理が面倒になるので、諦めました。
ワークフロー例
pixiv Sketch iOSアプリの現在のワークフロー&トリガー例は以下のような感じになっています。テスト・アプリの社内配布・App Store Connectへのアップロードを自動化しています。
テストの実行
Pull Requestに対してPushするたびに実行されます。
配布アプリの作成
developブランチにPushされるたびに、配布物を作るビルドを走らせて、アプリをインストールできるBitrise.ioへのリンク・QRコードをSlackに投げてます。ただし、こちらはリリース前の動作確認くらいにしか使っていません。以下で紹介していますが、GitHubのPull Requestのコメント上に配布物へのリンク・QRコードを載せて、そこから追加・変更した機能ごとにアプリの動作確認をすることが多いです。
ストアへのアップロード
releaseブランチにPushするたびにビルドナンバーを更新してApp Store Connectにアップロードしています。CrashlyticsへのdSYMのアップロードもここでやっています。
ライブラリのアップデートチェック
Bitriseはビルドをスケジューリングすることができるので、週1回くらいの頻度でライブラリのアップデートがあるかどうかチェックして、Slackに流しています。CocoaPodsやCarthageのoutdatedコマンドを利用しています。
本当は勝手にPull Requestを作るところまでを自動化して、確認してマージするだけにしたいので、そのうちやっていきたいですね。
GitHubのレビューコメントからビルドをする
Bitriseのビルドトリガーは主にコミットをpushしたときに発火するものが設定できますが、社内配布アプリを作るビルドはpushするたびに必要ではないので、GitHubのPull Requestに「ビルドして」とコメントしたら配布物を作るビルドが走るようにトリガーを自作しています。
GitHubのWebHookでGoogle App Scriptを通してBitriseのAPIを叩くことで、実現しています。(通常のコメントはIssue commentの扱いになってPull Requestの番号が取得できないので、レビューコメントの方を利用しています)
以下のような感じでAPIを叩いています。
GitHubのPull Requestにインストールページへのリンクをコメントする
ピクシブではアプリの社内配布はBitrise.ioを使用しています。Bitrise.io便利。Bitrise.ioのURLやQRコードをSlackに流すことでエンジニア以外も手軽にアプリをインストールすることができます。
SlackにポストするというステップはBitriseが用意してくれており、簡単にビルド結果などをSlackに流すことができるのですが、Slackだと「あのバージョンのビルドどこに行ったっけ...」と探すのに手間がかかってしまいますね。
BitriseのコミュニティステップにはGitHubのPull Requestにコメントするというものがあります。自分が作りました。
Pull RequestにコメントとしてBitrise.ioへのリンクが載っていれば、コードと動作の変更が追いやすくなって良いです。もちろん、GitHubのアクティビティがSlackに流れるようになっていれば、Slackにも勝手にBitrise.ioへのリンクが流れるのでエンジニア以外の人にもすぐインストールして試してもらうことができます。
Bitriseのステップは簡単に自作することができ、bitrise-steplib にPull Requestを送ることでコミュニティステップとしてBitrise上から誰でも使えるようになります。
秘伝のシェルスクリプトがある方など、ステップ化を検討してみてはいかがでしょうか!
おわりに
ピクシブでのBitrise使用状況を紹介してきました。
これ以外にも、毎日どのくらいビルドが行われたのか、ビルド時間やホールド時間はどのくらいだったのかを、GASを使ってBitriseのAPIを叩いてスプレッドシートに記録しています。導入したての頃は、これを参考にビルド時間を減らすためにワークフローを見直したり、プランの変更を考える材料にしていました。現在もこれを使って更に最適な最大同時ビルド数を検討しています。
まだまだ改善できる点はたくさんあるので、CIを改善して最高の成果を出せる環境を作るモバイルアプリエンジニアを募集しています!