この記事は、第2のドワンゴ Advent Calendar 2015の記事です。
はじめに
ここ最近のiOS界隈のトレンドの1つとしてfastlaneがあります。
fastlaneは様々なアクションを組み合わせて使用することで、テストやipaの作成などを簡潔に記述し実行することができます。
2015年10月25日のニコニコ超パーティにてリリースされた「ニコナレ」などドワンゴでリリースしていくiOSアプリにも今後積極的に使用していく予定です。
今回実際にプロジェクトに取り入れた例を踏まえつつ、これからfastlaneを初めて触る人がこの記事を見ればfastlaneの使い方、actionの定義の仕方などがわかるような記事を目指します。
また、多くの紹介記事ではAppStoreへのリリース自動化やデプロイ等に焦点を当てていますが、今回はテストでの利用やipaの作成など、デプロイフロー以外でもfastlaneを導入するための入門記事としてfastlaneの根本となる機能や作成方法をまとめます。
インストール
まずは、fastlaneのインストールを行います。
gem install fastlane
この場合、インストールを行ったfastlaneのバージョン等はそれぞれのPCの環境等に依存することとなります。
個人の開発の場合はそこまで問題はありませんが、チームでの開発やCIの環境を常に同じバージョンで動作させるためには、Bundlerを使用します。
Bundlerをインストールしていない場合、以下のコマンドを使用しインストールしてください
gem install bundler
プロジェクト直下にGemfile
を用意し、以下を記述します。
source "https://rubygems.org"
gem 'fastlane'
そして、fastlaneをvendor/bundle
配下にインストールします。
bundle install --path=vendor/bundle
fastlaneをvendor/bundle
配下にインストールすることで、することで各々の開発環境に依存することなくfastlaneを使用することができます。
Bundlerを使用して、fastlaneのインストールを行った場合、これからのfastlane
コマンドの前にbundle exec
を使用して、bundlerでインストールしたfastlaneを使用することを明記してください
ちょっとしたはまり
fastlaneインストール後、コマンドを使用しようとした所以下のエラーに遭遇しました。
https://github.com/fastlane/fastlane/issues/729
-bash: fastlane: command not found
システム標準のRubyを使用している場合に起きることがあるバグだそうです。
対応策
すでに対応策は明示されており、~/.bashrc
か~/.zshrc
に以下を追加した所動作しました。
export GEM_HOME=~/.gems
export PATH=$PATH:~/.gems/bin
こういったシステム依存の問題を少なくするためにも、Bundlerを使用してのインストールをおすすめします。
初期設定
fastlaneのセットアップは以下のコマンドで行います。
fastlane init
バージョン管理(git等)を使用しているかの確認。
していればy
、していなければgitを使ってバージョン管理を行って下さい。
Do you have everything commited in version control? If not please do so now!
(y/n)
fastlaneを使用するアプリのBundle Identifier
を入力してください。
ここで入力するBundle Identifier
はfastlaneからiTunesConnect等に接続するときに使用されますので、もしIdentifierを切り替えて使用している場合は本番用のものを入力してください。
App Identifier (com.krausefx.app):
Developerアカウントのメールアドレスを入力してください。
もし、Developer固有の機能(プロビジョンの更新等)を行わない場合は空でも問題ありません。
また、設定はAppfile
に書き込まれていますのでいつでも変更可能です。
Your Apple ID (fastlane@krausefx.com):
AppStoreへのデプロイなどに使用するdeliver
コマンドを使用する場合はy
を入力してください。
今回の記事ではデプロイを行わないため使用しません。
Do you want to setup 'deliver', which is used to upload app screenshots, app
metadata and app updates to the App Store? This requires the app to be in the App
Store already. (y/n)
アプリのスクリーンショットを取ってくれるsnapshot
を使用する場合はy
を入力してください。
snapshot
コマンドはUIAutomationを使用して実行時にスクリーンショットを自動で撮影してくれます。
deliver
同様今回の記事では含みません。
Do you want to setup 'snapshot', which will help you to automatically take
screenshots of your iOS app in all languages/devices? (y/n)
sigh
コマンドは自動でDeveloperサイトからプロビジョンニングファイルのダウンロードや更新などを行うことができます。
y
を入力すると自動でsigh
を使用したサンプルがFastfile
に追加されます。
Do you want to use 'sigh', which will maintain and download the provisioning
profile for your app? (y/n)
プロジェクト内でカスタムスキームを使用している場合は入力してください。
もし、Xcodeデフォルトのままですとなにも入力する必要はありません。
Optional: The scheme name of your app (If you don't need one, just hit
Enter):
この時点で./fastlane
というフォルダが生成され、
- Appfile
- Fastfile
といったファイルが自動生成されています。
基本的にfastlaneを使用して処理を行うにはこのFastfile
に様々な処理を記述していきます。
Fastfileの中身を見てみると基本的に4つの処理があることがわかります。
before_all
ここでは、fastlaneの処理が開始される前に一度だけ実行されます。
before_all do
# ENV["SLACK_URL"] = "https://hooks.slack.com/services/..."
cocoapods
# increment_build_number
# xctool # run the tests of your app
end
ENV["SLACK_URL"]
にslackのincoming hook url
を設定しておくことにより、各アクションに設定された自動投稿やslackへの通知が簡単に行うことができます。
cocoapods
ではpod install
コマンドが実行されます.
このように処理の前に必ず行っておきたい初期化処理などはこのbefore_all
で行います。
lane
fastlaneでは1つの動作の流れをlane
と呼んでいます。
fastlaneを実行する際は引数としてlane_name
を渡します。
fastlane [lane_name]
このlane_name
に対応したlaneが実行されるようになります。
desc "Runs all the tests"
lane :test do
# snapshot
end
例えば、上記のlane :test
を実行するためには以下のコマンドにより行うことができます。
fastlane test
after_all
処理の終了時にはafter_all
が呼び出されます。
after_all do |lane|
# This block is called, only if the executed lane was successful
# slack(
# message: "Successfully deployed new App Update."
# )
end
ここでは、実行終了時の通知などをslackに通知したりします。
|lane|
の中には実行したlane
の種類が格納されていますので、test
というlaneだけ終了通知を行いたい場合は以下のような判定を行うことができます。
after_all do |lane|
if lane == :test
slack(message: "finish lane")
end
end
error
処理中になんらかの理由でエラーが発生し処理が中断された場合はerrorが呼び出されます。
一度errorのブロックに入るとafter_all
は呼び出されずここで終了するので気をつけて下さい。
error do |lane, exception|
# slack(
# message: exception.message,
# success: false
# )
end
このようにFastfile自体は4つの基本的には動作のみで処理を記述することができ、各laneを拡張していくという流れになります。
laneの定義
前述したとおりfastlaneではlaneという流れを使用して処理を行います。
ここでは、cocoapodsのインストールとcathageのインストールのみを行うlaneを定義してみたいと思います。
lane :setup_library do
cocoapods
cathage
end
このようにlane
の中で予め定められたアクションを記述するだけで、CocoapodsとCarthageを使用したライブラリのセットアップを簡単に行えます。
このlaneを実行させるためには以下のコマンドで実行できます
fastlane setup_library
laneの順次実行
定義したlaneはlane内で別のlaneを呼ぶことも可能です。
lane :deploy do
build(release: true)
# deploy code
end
lane :deploygate do
build
# update deploygate
end
lane :build do |options|
scheme = (options[:release] ? "Release" : "Staging")
ipa(scheme: scheme)
end
ここでは、deploy
とdeploygate
のlaneでどちらもipaの出力を行いたい場合はbuild
というlaneを別で定義して各lane内で呼び出しています。
laneの呼び出しは引数も取ることができ、deploy
のlaneではrelease
フラグを引数としてわたしています。
プロジェクトのビルドとipaの出力
プロジェクトのビルドとipaの出力は別々のアクションとして定義されていますが、gymというビルドとipaの出力を比較的に簡単に行えるアクションが用意されています。
gym
を使用することでビルドとipaの出力のコードは以下の様な形となります。
gym(
workspace: "MyApp.xcworkspace",
configuration: "Debug",
scheme: "MyApp",
silent: true,
clean: true,
output_name: "my-app.ipa",
)
ここではプロジェクト設定された値を使用してAppStore用のipadをmy-app.ipa
という形でアーカイブしています。
テストの実行
fastlaneでのテストを実行はscan
やxctest
、xctool
等複数のツールを使用することができます。
この中でも比較的新しく簡単にテストを行うことができるscan
コマンドをおすすめします。
scan
は以下の記述で使用することができます。
scan(scheme: "ApplicationSchemeName")
Slackへの通知を設定した場合は、テストに成功すると以下のような通知を自動で送信されます。
また、scan
内部でxcprettyと呼ばれるログ整形ツールが使用されており、テストの結果はJUnitのレポート形式のhtmlファイルが./fastlane/test_output/report.html
に出力されています。
出力される場所は別途指定可能です。
scanコマンドは様々な引数を取ることが可能でありscan --help
コマンドで使用できる引数を見ることができます。
ここでは主に使用するであろう代表的なコマンドのみ抜粋します。
-w, --workspace
-p, --project
-a, --device
-s, --scheme
-c, --clean
-q, --configuration
--skip_slack
--slack_only_on_failure
上記のコマンドを組み合わせることにより、scan
実行時の条件等を変更することができます。
例えば、
・xcworkspace
を使用しているプロジェクト
・テスト前にクリーンを行う
・slackへの通知はテストに失敗した時のみ行う
ような設定を行いたい場合は
scan(
workspace: "Application.xcworkspace",
clean: true
slack_only_on_failure: true
)
のような形となります。
レポートをSlackに通知
fastlane1.45.0より出力されたレポートのパスを取得することができます。
この機能により、簡単にslack等にテスト結果を通知することが可能です。
slack(
message: "Tests results: " + ENV['FL_REPORT_PATH']
)
アクションを探す
fastlaneのアクションには様々な種類があり、日々開発者によってそのアクションの数は増大しています。
まず、行いたい動作がある場合は、action一覧がまとまっている
https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Actions.md
このページを参照してください。
fastlaneで使用できるアクションは基本的にすべてここにまとまっています。
アクションに使用できる引数を確認する
主要アクション
以下のようなfastlaneが公式に開発を行っている機能に関しては基本的には全て単体のコマンドとしてコマンドライン上で使用することができます。
- fastlane
- deliver
- snapshot
- scan
- gym
- etc.......
このコマンドに関しては引数の実装を確認するためにはscan
の時と同様にコマンドライン上で--help
で確認するのが一番はやいと思います。
例えば、gymのコマンドはAction一覧で記述されている引数よりも多くの引数を指定することができます。
サンプルだけの引数を使用しているとipaのアーカイブの方法はAppStore
へのリリースのためのアーカイブとなってしまいます。
gym(
workspace: "MyApp.xcworkspace",
configuration: "Debug",
scheme: "MyApp",
silent: true,
clean: true,
output_name: "my-app.ipa",
)
Deploygateなどに配布するためのAdHoc
配信用のアーカイブをするためには
gym(
workspace: "MyApp.xcworkspace",
configuration: "Debug",
scheme: "MyApp",
silent: true,
clean: true,
output_name: "my-app.ipa",
export_method: "ad-hoc"
)
のようにexport_method
をad-hoc
にする必要があります。
コマンドを実行し、何かエラーに遭遇することがあったらまず--help
を使用し、使用できる引数がないか確認してみてください。
その他カスタムアクション
fastlaneのアクションの実装ファイルは
https://github.com/fastlane/fastlane/tree/master/fastlane/lib/fastlane/actions
全てここに定義されています。
アクションの引数を確認する場合は各々のアクション実装ファイルを見ることで確認できます。
ここでは、Carthage
を例に見ていきます。
https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/actions/carthage.rb
cmd = ["carthage bootstrap"]
cmd << "--use-ssh" if params[:use_ssh]
cmd << "--use-submodules" if params[:use_submodules]
cmd << "--no-use-binaries" if params[:use_binaries] == false
cmd << "--no-build" if params[:no_build] == true
cmd << "--verbose" if params[:verbose] == true
cmd << "--platform #{params[:platform]}" if params[:platform]
Carthageの実装ファイルの7-12行目にこのようにパラメータからコマンドを作成している行があります。
params[:no_build]
この:no_build
が
carthage(
no_build: true
)
fastlane上の引数のno_build
に対応しています。
そのため、fastlane上でCarthageのビルドをiOSのみにする場合は
carthage(
platform: "iOS"
)
のような形にすることでiOSのみのビルドでCarthageを動作させることができます。
このようにfastlaneはアクション毎にある程度定められたフォーマットで動作が定義されているため、比較的簡単に動作を確認したり、引数のチェックを行うことができます。
カスタムパラメータ
fastlane
実行にカスタムパラメータを渡すことができます。
現在、自分はPullReuqestBuilderを使用してJenkinsでfastlaneを動作させテストを行わせています。
その際、テストの終了時に対象のプルリクエストのURLをSlackに通知するという処理を行っています。
PullRequestBuilderの説明は省略させてもらいますが、Jenkins上で${ghprbPullLink}
でプルリクエストのリンクを取得することができます。
fastlane実行時にkey:value
のような形でパラメータを指定することができます。
fastlane jenkins prurl:${ghprbPullLink} key:value
渡されたたパラメータは|options|
の中に格納されoptions[:key]
で使用することができます。
lane :jenkins do |options|
# テストの実行
# scan
# プルリクエストリンクをSlackに通知
slack(
message: "Succeed all tests: " + options[:prurl]
)
end
Jenkins
今回初めにfastlaneを導入しようとしたきっかけはJenkins上でビルドやテストを走らせる際の設定がかなり属人化してしまい、管理者以外がいじりにくいという問題を解消させるために導入しました。
ビルドやテストなどの実行を各pluginやシェル上で行わずfastlaneに全て移行することで、プロジェクトが増えてもfastlaneを設定するだけでよく、JenkinsはあくまでもGithubからのプルリクエストの受け口やfastlaneの実行だけの役割を持つだけでよくなります。
また、開発機からのデプロイフローも自動化することができます。
このように、AppStoreへのリリース以外にもfastlaneは存分に使用できますので、fastlaneをまだ使用したことがない方はぜひこの機会にdeploygateやcrashlyticsへのデプロイ、テスト実行だけでもfastlaneに移行してみてください!
Jenkins実行時のはまり
- 設定にかなり依存しますが、Jenkins上のコマンドラインから実行する際、LANGの設定でエラーが出る場合はあります。
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
その場合はfastlane
の実行前にexport
を行ってやってやるか、Jenkinsの環境設定よりLANGを設定してください。
まとめ
ここまで、基礎の基礎となる紹介をしてあまり実践的な内容に触れることはできませんでしたが、一度fastlaneの基礎を学習することにより様々な拡張を行うことができるかと思います。
時間があれば、ここからもう少し実践的にAppStoreへのデプロイやプロビジョニングプロファイルの取り扱い等の内容を記事にできればと思っています。
iOSアプリ開発を行ううえで便利ツール等は年々増加しています。
適度にツールを導入し、快適なアプリ開発生活を送りましょう٩(๑❛ᴗ❛๑)۶