はじめに
こんにちは、iOSエンジニアの dayossi です。
家族が幸せになれるサービスを提供したいと思って、
HaloHaloという家族日記アプリをリリースしています。
今回は、Firebaseが提供しているアプリのテスト配布ツールFirebase App Distribution
を
fastlaneから呼び出して、テスト配布を自動化する中で詰まった点を共有いたします。
fastlaneがRubyで構成されているにもかかわらず
私はRubyでの開発は全くやったことがないので、
ほぼ手探り状態でfastlaneを試しました。。
先人の方々の叡智を参考に
なんとかfastlaneを実行してipaファイルをビルドできる状態まで辿り着きましたが
肝心のFirebase App Distributionへデプロイできず、
かなり詰まりました。
同じような境遇で悩まれている方の参考になりましたら幸いです。
前提
以下の構成で、fastlaneからFirebase App Distributionへデプロイするつもりでした。
(fastlaneを実行したいプロジェクト名)
├ (各種プロジェクトファイル)
├ Gemfile # fastlane実行・プラグイン呼び出しを管理。
├ Gemfile.lock
└ fastlane
├ .env.default # 環境変数を管理。以下のファイルから参照される。
├ Appfile # app_identifier, apple_idを管理
├ Fastfile # fastlane実行内容を管理
└ Pluginfile # fastlane実行時に使用するプラグイン実行を管理
default_platform(:ios)
platform :ios do
desc "deploy STG on Firebase App Distribution"
lane :distribution do
# cocoapodsインストール
cocoapods
# .ipaファイルの作成
gym(
workspace: ENV["WORK_SPACE_NAME"],
scheme: ENV["SCHEME_NAME"],
export_method: "ad-hoc",
export_options: {
method: 'ad-hoc',
provisioningProfiles: {
ENV["BUNDLE_IDENTIFIER"] => ENV["TARGET_PROVISIONING_PROFILES"],
},
},
export_xcargs: "-allowProvisioningUpdates",
)
# firebase app distributionに.ipaアップロード
firebase_app_distribution(
app: ENV["FIREBASE_APP_ID"],
groups: ENV["TEST_TARGET_NAME"],
release_notes: "this is fastlane test",
# firebase_cli_path: "node_modules/.bin/firebase",
)
end
end
# frozen_string_literal: true
source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"
plugins_path = File.join(File.dirname(__FILE__), '.', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path)
# Autogenerated by fastlane
#
# Ensure this file is checked in to source control!
gem "fastlane-plugin-firebase_app_distribution", git: "https://github.com/fastlane/fastlane-plugin-firebase_app_distribution"
- Fastlaneのdistributionレーンを実行すると、以下の順序で処理が実行される想定
- Xcodeのアーカイブで生成される ipaファイルを作成
- firebase app distributionへipaファイルをアップロードする
- テストアプリ配布が完了
-
fastlane-plugin-firebase_app_distribution
を、bundleコマンドでインストール済み - 対象レーンは問題なく呼び出せ、実行可能
-
distribution
アクション内のfirebase_app_distribution
アクションは、Pluginfileに定義したgemから呼び出す想定
ことの始まり
上記の前提をもとに、いざレーンを呼び出してみましたが。。
[11:11:50]: Could not find action, lane or variable 'firebase_app_distribution'. Check out the documentation for more details: https://docs.fastlane.tools/actions
+------+------------------+-------------+
| fastlane summary |
+------+------------------+-------------+
| Step | Action | Time (in s) |
+------+------------------+-------------+
| 1 | default_platform | 0 |
| 2 | cocoapods | 1 |
| 3 | gym | 36 |
+------+------------------+-------------+
[11:11:50]: fastlane finished with errors
[!] Could not find action, lane or variable 'firebase_app_distribution'. Check out the documentation for more details: https://docs.fastlane.tools/actions
distributionレーン内で定義した、firebase_app_distributionというaction, レーン・変数は見つかりませんでした
のようなエラー表示が出て終了しました。
Pluginfileに記載したファイルから
firebase_app_distribution
アクション・レーンなりが見つかりそうなものなんですが
うまくいきませんでした。
プラグインを呼び出せない原因を探ってみたところ、
問題はGemfileでのプラグイン呼び出しに原因がありました。
今回の問題分析
やりたかったこと
fastlaneを実行したいプロジェクト内のfastlane/Pluginfile
で指定したプラグインのファイルを実行したい。
分析
そもそもRuby自体をほとんど触ったことがなく、基本的なところの理解ができていなかったので
まずは「fastlane実行時にプラグインを呼び出すには?」を整理しました。
fastlane実行時にプラグインを呼び出すには?
大まかな流れは、以下のように解釈しました。
1. bundle exec fastlane (レーン名)実行
2. Gemfile.lockを見る
3. Gemfile内のgemからfastlaneを実行
4. Gemfile内の他のgemを実行
5. Fastfileを見る
6. 各レーン内で、定義されたアクションを実行する
※ fastlaneの基本アクション以外のアクションを使用する場合は、別途アクションファイルを読み込んでおく必要がある
今回は、6.で'firebase_app_distribution'というアクションはありません
エラーが出ましたので
まずはfirebase_app_distribution
アクションの出どころを整理しました。
fastlaneで定義されている基本アクションの中には、firebase_app_distribution
というアクションはありませんでした。
firebase_app_distribution
アクションは、外部から別途ファイルを読み込む必要がありました。
(アクション提供元:https://github.com/fastlane/fastlane-plugin-firebase_app_distribution)
Pluginfileには記載していたので、
4. Gemfile内の他のgemを実行
で何か不具合があると推測しました。
外部プラグインを呼び出す箇所は、以下の通りです。
source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"
# 以下、問題箇所
# プラグインを実行するファイルパスを取得する
plugins_path = File.join(File.dirname(__FILE__), '.', 'Pluginfile')
# 以上、問題箇所
# 上記で指定したファイルパスから、ファイルを読み取ってインスタンス化する
eval_gemfile(plugins_path) if File.exist?(plugins_path)
記述内容の整理
Fileは、RubyのFileクラスを指します。
File.joinは、各引数で指定した文字列を結合するFileクラスの関数です。
File.dirname(FILE)は、宣言されたファイルのパスを返すFileクラスの関数です。
(この場合は、Gemfileのパスを取得します)
本当なら (プロジェクト内のGemfileのパス)/fastlane/Pluginfile
のようなパスをplugins_path
に渡す必要がありますが、
File.join
の第二引数が '.'となっており、
(プロジェクト内のGemfileのパス)/(プロジェクト内のGemfileのパス)/Pluginfile
というパスが渡されていました。
そのため、ファイル読み取りに失敗し
'firebase_app_distribution'というアクションはありません
と警告されていたようでした。
対応
第二引数に 'fastlane'を指定し、(プロジェクトのルートパス)/fastlane/Pluginfile
となるように修正しました。
source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"
# 以下、問題箇所
# (プロジェクトのルートパス)/fastlane/Pluginfile を取得できるように修正
plugins_path = File.join(File.dirname(__FILE__), 'fastfile', 'Pluginfile')
# plugins_path = File.join('.', 'fastfile', 'Pluginfile') // この記述でも実行できました
# 以上、問題箇所
# 上記で指定したファイルパスから、プラグインを実行する
eval_gemfile(plugins_path) if File.exist?(plugins_path)
修正後の結果
[10:59:13]: Using deprecated option: '--firebase_cli_path' (This plugin no longer uses the Firebase CLI)
[10:59:13]: ---------------------------------------
[10:59:13]: --- Step: firebase_app_distribution ---
[10:59:13]: ---------------------------------------
[10:59:13]: No authentication method specified. Using cached Firebase CLI credentials.
[10:59:13]: 🔐 Authenticated successfully.
[10:59:13]: ⌛ Uploading the IPA.
[10:59:17]: ✅ Uploaded IPA successfully; updated provisioning profile of existing release 1.0 (5).
[10:59:18]: ✅ Posted release notes.
[10:59:19]: ✅ Added testers/groups.
[10:59:19]: 🎉 App Distribution upload finished successfully.
無事にfirebase app distributionプラグインを実行でき、テスト配布できました🥳
まとめ
そもそも、fastlaneがRubyで構成されていることを理解できていなかったため
問題の切り出しが難しいと感じていたことがわかりました。
(fastlaneのGithubを見ると、しっかりRubyで構成されていることがわかるのに。。)
ホントに初歩的なつまづきでしたが、今回の件でfastlaneの基本的なところを学べました。
雑記
fastlaneのfirebase_cli_pathオプションは、今後使えなくなる可能性があることを留意しておきたいと思います。