wootan's diary

iOSアプリ開発を中心としたエンジニアブログ

Relux iOSアプリ開発にfastlaneを導入してテストアプリ配信を自動化

ポケモンGOが盛り上がっていますね!
ようやく60種類あつめました。コンプリートにはまだまだかかりそうです...

本エントリでは fastlane の導入について書きたいと思います。
fastlaneを導入することでテストアプリの配信コスト、AppStoreの申請コストを
大幅に削減することができました。ぜひ参考にしてみてください。

fastlaneとは

XcodeiTunes Connect 上で行う
リリースフローの作業を自動化することができるツールです。

レールの概念

fastlaneにはレールという概念が存在します。
リリースフローの作業(テスト配信、AppStoreの申請など)を
それぞれをレーンとみなし、提供されているアクションを
組合せてレーンを作成します。
用意されているものだけでも十分ですが
プロダクトに合わせてカスタマイズすることも可能です。

導入方法

基本的にコンソールの指示に従っていくだけで初期設定が完了します。

#インストール
$ sudo gem install fastlane

#初期化
$ fastlane init

#画面の指示にしたがって値を入力していく
Your Apple ID (e.g. fastlane@krausefx.com): XXX@XXX.XXX
Starting login with user 'XXX@XXX.XXX'

-------------------------------------------------------------------------------------
The login information you enter will be stored in your Mac OS Keychain
You can also pass the password using the `FASTLANE_PASSWORD` env variable
More information about it on GitHub: https://github.com/fastlane/credentials_manager
-------------------------------------------------------------------------------------

Password (for XXX@XXX.XXX): *****

+----------------+-------------------------------------------+
|                      Detected Values                       |
+----------------+-------------------------------------------+
| Apple ID       | XXX@XXX.XXX                           |
| App Name       | relux                                     |
| App Identifier | XXX.XXX.relux                         |
| Workspace      | /Users/XXX/relux_ios/relux.xcworkspace    |
+----------------+-------------------------------------------+

Please confirm the above values (y/n)
y

Created new file './fastlane/Appfile'. Edit it to manage your preferred app metadata information.
Loading up 'deliver', this might take a few seconds
Login to iTunes Connect (XXX@XXX.XXX)
Login successful

+--------------------+-------------------------+
|            deliver 1.10.3 Summary            |
+--------------------+-------------------------+
| username           | XXX@XXX.XXX          |
| app_identifier     | XXX.XXX.relux        |
| metadata_path      | ./fastlane/metadata     |
| screenshots_path   | ./fastlane/screenshots  |
| skip_binary_upload | false                   |
| skip_screenshots   | false                   |
| skip_metadata      | false                   |
| force              | false                   |
| submit_for_review  | false                   |
| automatic_release  | false                   |
+--------------------+-------------------------+

Writing to 'fastlane/metadata/ja/description.txt'
Writing to 'fastlane/metadata/ja/keywords.txt'
Writing to 'fastlane/metadata/ja/release_notes.txt'
Writing to 'fastlane/metadata/ja/support_url.txt'
Writing to 'fastlane/metadata/ja/marketing_url.txt'
Writing to 'fastlane/metadata/ja/name.txt'
Writing to 'fastlane/metadata/ja/privacy_url.txt'
Writing to 'fastlane/metadata/copyright.txt'
Writing to 'fastlane/metadata/primary_category.txt'
Writing to 'fastlane/metadata/secondary_category.txt'
Writing to 'fastlane/metadata/primary_first_sub_category.txt'
Writing to 'fastlane/metadata/primary_second_sub_category.txt'
Writing to 'fastlane/metadata/secondary_first_sub_category.txt'
Writing to 'fastlane/metadata/secondary_second_sub_category.txt'
Successfully created new configuration files.
Downloading all existing screenshots...
Downloading existing screenshot '1_iphone4_1.4.0inc-01.jpg'
Downloading existing screenshot '2_iphone4_2.4.0inc-02.jpg'
Downloading existing screenshot '3_iphone4_3.4.0inc-03.jpg'
Downloading existing screenshot '4_iphone4_4.4.0inc-04.jpg'
Downloading existing screenshot '5_iphone4_5.4.0inc-05.jpg'
Downloading existing screenshot '1_iphone35_1.3.5inc-01.jpg'
Downloading existing screenshot '2_iphone35_2.3.5inc-02.jpg'
Downloading existing screenshot '3_iphone35_3.3.5inc-03.jpg'
Downloading existing screenshot '4_iphone35_4.3.5inc-04.jpg'
Downloading existing screenshot '5_iphone35_5.3.5inc-05.jpg'
Downloading existing screenshot '1_iphone6_1.4.7inc-01.jpg'
Downloading existing screenshot '2_iphone6_2.4.7inc-02.jpg'
Downloading existing screenshot '3_iphone6_3.4.7inc-03.jpg'
Downloading existing screenshot '4_iphone6_4.4.7inc-04.jpg'
Downloading existing screenshot '5_iphone6_5.4.7inc-05.jpg'
Downloading existing screenshot '1_iphone6Plus_1.5.5inc-01.jpg'
Downloading existing screenshot '2_iphone6Plus_2.5.5inc-02.jpg'
Downloading existing screenshot '3_iphone6Plus_3.5.5inc-03.jpg'
Downloading existing screenshot '4_iphone6Plus_4.5.5inc-04.jpg'
Downloading existing screenshot '5_iphone6Plus_5.5.5inc-05.jpg'
Successfully downloaded all existing screenshots
Successfully created new Deliverfile at path 'fastlane/Deliverfile'
'snapshot' not enabled.
'cocoapods' enabled.
'carthage' not enabled.
Created new file './fastlane/Fastfile'. Edit it to manage your own deployment lanes.
fastlane will send the number of errors for each action to
https://github.com/fastlane/enhancer to detect integration issues
No sensitive/private information will be uploaded
You can disable this by adding `opt_out_usage` to your Fastfile
Successfully finished setting up fastlane

テストアプリ配信の自動化

弊社ではdeploygateを利用しており手順は以下のようになります。
fastlaneでは全ての工程を自動化することができます。

テストアプリ配信フロー

f:id:wootan1102:20160729195028p:plain

1. pod install の実行
2. アプリケーションのビルド
3. プロビジョニングファイルの更新
4. ipaファイルの生成
5. deploygateへのアップロード

Fastfile

fastlane/Fastfileに実行させたいアクションを書いてきます。
initした状態で一通りのものは揃っているので
どういう書き方をすれば良いか迷うことはないと思います。

事前処理

レーンを実行する前の事前処理を書いておくことができます。

  • 実行後にSlackに通知できるようにWebhookURLを設定
  • cocoapods pod installの実行
before_all do
   ENV["SLACK_URL"]="XXXXX"
   cocoapods
end
deploygateレーン

deploygate配信用のレーンを新しく用意しています。
アップロードする際のメッセージは最後のコミットメッセージを設定しています。

  • sigh プロビジョニングファイルの更新
  • gym アプリケーションのビルド
  • deploygate deploygateへのアップロード
lane :dg do
   sigh(adhoc: true)
   gym(scheme: "relux", configuration: "Debug")
   message = "relux for iOS\nCommit message: #{last_git_commit[:message]}"
   deploygate(user: "XXXXX", api_token: "XXXXX", message: message)
end
事後処理

レーン実行した後の処理を書くことができます。
ここでは レーンが成功したことをSlackに通知するようにしています。

after_all do
   slack(message: "Successfully fastlane.")
end
Slack上ではこのように表示されます。

f:id:wootan1102:20160729194950p:plain

レーンの実行

今回紹介したdeploygateはこのように実行します。

$ fastlane dg

とても簡単です。導入前は手動でアップロードしていたのですが
コマンド1つでアップロードできるようになりかなり楽になりました。
deploygateには必ず最新版のテストアプリがあるという状態を保つことができています。

AppStoreへの申請についても自動化することができるので次回紹介したいと思います。