こんにちは。乗換案内のiOSアプリの開発を担当している田中 (@tattn)です。
ここ最近、アプリの品質を担保するための手段として継続的インテグレーション (CI: Continuous Integration)や、アプリのリリースコストを削減するための継続的デリバリ (CD: Continuous Delivery) が注目されています。
そこで今回は、自分が担当している乗換案内のiOSアプリで活用しているCI/CDの仕組みをご紹介したいと思います。
まずはiOSアプリの開発フロー自動化ツールのデファクトスタンダード fastlane について簡単に触れます。乗換案内もfastlaneを活用しています。
fastlane
https://github.com/fastlane/fastlane
fastlaneは、iOSとAndroidのビルドやテスト、デプロイなどを簡単なスクリプトで実行できるようにするツールです。アプリ開発に必要な作業を実行してくれる機能 (Action) が豊富に用意されており、また、設定ファイルはRubyで記述できるため、非常に簡単かつ柔軟に設定をすることが出来ます。
簡単に導入方法をご紹介します。
※ 環境: Ruby (2.4.2p198), fastlane (2.68.0)
導入
iOSのプロジェクトのルートディレクトリに以下の内容のGemfileという名前のファイルを置きます。
source 'https://rubygems.org'
gem 'fastlane'
Bundlerでインストールします。
$ bundle install --path=vendor/bundle
設定
fastlane init
でテンプレートを作成します。
$ bundle exec fastlane init
CLI上でアプリやアカウント情報の質問に答えていくと ./fastlane/Fastfile
などが生成されます。このファイルがfastlaneの主な設定ファイルです。
# コメントなど一部改変してます
fastlane_version "2.68.0"
default_platform :ios
platform :ios do
before_all do
cocoapods # CocoaPodsを利用したライブラリのビルド
carthage(platform: 'ios') # Carthageを利用したライブラリのビルド
end
desc "テストを実行するレーン"
lane :test do
run_tests # XCTest/XCUITestの実行
end
desc "Test Flightにアップロードするレーン"
lane :beta do
build_app # ビルド
upload_to_testflight # Test Flightにアップロード
end
desc "App Storeにアップロードするレーン"
lane :release do
build_app # ビルド
upload_to_app_store(force: true, submit_for_review: true) # アップロードし、アプリを申請
end
end
シンプルなプロジェクトの場合は、これだけの設定でCI/CDに必要な基本的な機能を用意することが出来ます。
※ fastlane 2.68.0からアクション名が変わりました。気になる方は iOS Advent Calendar 2017 に書いた fastlaneの便利な機能を徹底的に活用しよう をご覧ください。
実行
ターミナルで下記のコマンドを実行すると、Fastfile
に定義したbeta
レーン を実行できます。「レーン」が fastlaneの一つの実行単位となります。
$ bundle exec fast lane beta
これだけでTest Flightで配信ができます。とてもわかりやすくて、簡単ですね。
fastlaneの機能 (Action) はこちらで確認できます。https://docs.fastlane.tools/actions/
CIサービス
fastlaneはローカルのMacでも動かすことが出来ますが、CIサービス (サーバ) 上で動かすことが多いです。
理由としては以下のような点が挙げられます。
- GitHubのWebhookと連携しやすい
- ローカルの環境に依存しない
- ローカルの端末で実行待ちをしなくて良い
よく使われているCIサービス/ツールにはこのようなものがあります。
- サービス
- ツール
それぞれ、機能や料金などが異なり、よく検討して選定する必要があります。
ヤフーでは、簡単かつ高機能なCI環境が社内に用意されています。続いてはその社内プラットフォームについてご紹介します。
Approduce
社内には Approduce (アップルジュース) という、アプリのビルド、テスト、配布、リリースをサポートするプラットフォームがあります。Web上でリポジトリやブランチなどの簡単な設定をし、fastlaneの設定をするだけで、CIサーバ上でfastlaneを実行したり、アプリのインストール用Webページを作成したりすることなどができます。また、Approduceには専用のfastlaneアクションも用意されており、社内システムとの連携が簡単にできるようになっています。
乗換案内のアプリでもApproduceを利用しています。それではfastlaneとApproduceを利用した開発とリリースフローのご紹介をします。
乗換案内の開発フロー
乗換案内アプリは、以下のようなフローでアプリの開発をしています。
- 機能の追加や修正を行い、プルリクエストを送ります。
- プルリクエストが送られると、アプリの自動ビルド・テスト・Lintなどが行われます。
- ビルドに成功するとアプリのダウンロードリンクが、問題がある場合はその理由などがプルリクエストのコメントに付きます。
- レビュアーはコードレビュー時に、必要に応じてアプリをインストールし、挙動を確認します。
- 問題がなければマージします。
- 1-5を繰り返して、アプリの次のリリースに必要な実装を追加します。
- 機能の実装とテストの完了後、Approduceのリリースボタンを押して、アプリの申請をします。
細かく説明するとかなりの量になってしまいますので、今回の記事のテーマ「CI/CD」に関係する部分について、掘り下げていきます。
自動ビルド・テストと自動配布
プルリクエストを送ると自動でいくつかの処理を実行してくれます。
まず1つ目は、SwiftLintというツールです。こちらはコードのスタイルをチェックしてくれます。これによって、自動でプロジェクトのコーディング規約を満たしているかなどをチェックできます。
次に、Dangerというプルリクエストの形式チェックツールを実行します。「マイルストーンが設定されているか」、「UI変更時には概要にアプリのスクショが貼られているか」などをチェックしています。全てのチェックをパスした際は、LGTM画像を貼ってくれます (笑)
続いて、ユニットテストやUIテストを実行しています。乗換案内ではUIテストに Appium を使用しています。社内にはAppiumの実行結果をWeb上でわかりやすく閲覧できる仕組みもあります。またUIテストの実行にはどうしても時間がかかってしまうため、Approduceの設定で簡単にON/OFFを切り替えられるようにしています。
そして、アプリのビルドと配布を行っています。ビルドが完了するとプルリクエストのコメントに QRコード付き でダウンロード先を教えてくれます。
※ 「QRコード」はデンソーウェーブの登録商標です。
UI系の変更は実際に触って確認してみないとわからないことも多いので、QRコードで簡単にアプリがインストールできると非常に確認がスムーズです。
また、Approduceには専用の iOS アプリもあり、 いつでも過去の任意のビルドを実機でインストール することができます。
プルリクエストを出すだけでここまで様々なことをしてくれるようにしています。仕組みの導入前と比べて明らかに開発が効率的になっている感覚があります。
補足ですが、これらの処理を直列に実行してしまうとすべての処理が終わるまでにかなりの時間がかかってしまいます。Approduceには、fastlaneのFastfileに数行書くだけでこれらを 並列で実行してくれる仕組み があります。このおかげで、乗換案内では数分で自動テストやアプリの配布が終わっています。 (UIテストを実行した場合はもう少し時間がかかります)
リリース
すべての実装やテストの完了後、アプリの申請を出します。
申請を出すためにはアプリのリリースノートやスクリーンショットなどをApp Store Connectで設定したり、アーカイブしたアプリをアップロードして、審査対象のビルドとして登録する必要があります。
乗換案内ではこれらの作業にもfastlaneとApproduceを利用しています。
例えば、リリースノートやスクリーンショットなどのメタデータはfastlaneの upload_to_app_store
(deliver
) という機能を利用して設定しています。乗換案内では、メタデータは企画や制作の方に作成していただき、アプリのリポジトリにプルリクエスト を出してもらっています。プルリクエスト上でメタデータの変更をみると、差分が非常に見やすいです。
他にも、アプリのアップロードや申請もfastlaneの upload_to_testflight
(pilot
) や upload_to_app_store
の機能を利用したり、fastlaneの内部クラスを利用して作成したオリジナルの機能を用いて自動化しています。
ApproduceにはボタンでFastfile内のlaneを実行できる機能があり、必要なタイミングで処理を実行することもできるようになっています。これによっていつでもApp Store Connectとの手続きを自動実行することが出来ます。
fastlaneはOSS
こんなにも便利なfastlaneはOSS (Open Source Software) になっており、誰でも実装を読んだり、プルリクエストを出すことができます。
色々な自動化を設定している間に自分はたまたまバグを見つけて、プルリクエストを出してみました。
fix the checking of URLs containing non-ASCII characters and a fragment identifier #10886
fastlaneのメンテナーはとても活発に活動しており、このプルリクエストは就寝前に送ってみたのですが、翌日目が覚めたときにはすでにマージされていました (笑) それほどのスピード感で開発されています。
寝る前に送ったfastlaneへのPRが起きたらマージされてたw 早いwhttps://t.co/XzTqQmbXDx
— Tatsuya Tanaka (@tanakasan2525) 2017年11月14日
App Store ConnectやXcodeの大きな更新の直後は動かなくなることもありますが、このスピード感で迅速に修正されていますので、とても信頼できるツールだと思っています。
最後に
以上が乗換案内アプリで実践しているCI/CDの大まかなご紹介となります。何か気づくこと、参考になることがありましたら幸いです。
最後にお知らせです。
つい先月ですが、ヤフー主催でiOSアプリの品質に関して、各社がどのように向き合っているのかをテーマとした勉強会が開催されました。
Bonfire iOS #3
https://yj-meetup.connpass.com/event/71599/
https://togetter.com/li/1176813
iOSの勉強会では話されることが少ないQAについての発表もあり、個人的にも勉強になることが多い会でした。
今回は「品質」がテーマでしたが、毎回テーマを変えて開催しています。また、iOS以外にもAndroidやデザインなど、様々な技術やデザインの領域での開催をしています。
connpassの「Yahoo! JAPAN」グループのメンバーに入ると開催前にメールや通知が届いて便利ですよ。ご興味がありましたら、ぜひ次回ご参加してみてください!
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました