PLAY DEVELOPERS BLOG

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

fastlane を使用したアプリビルドの自動化

OTTサービス事業部で iOSアプリ開発を担当しております片山です。
プライベートで使用しているのはAndroidです。

今回の主題

今回の主題はずばり アプリバイナリ作成の自動化 です。

iOS/Androidアプリを開発する上で避けては通れないものとして、アプリケーションを1つに固める作業があります。
ArchiveGenerate Signed Bundle などいろいろ名称はありますが、これを行わなければApp StoreやGoogle Playに公開することはできません。
また、社内テストや(エンドユーザーではない)顧客への受け入れ確認などを考えると、この作業の回数は途方もなく多くなります。

そしてこの作業は、Xcodeから行うと1環境分を作るのにビルドで待たされ、終わったあとにまたGUIでの操作が必要になります。
本番環境用にArchiveを始め、10分ほど待たされ、コーヒーを淹れて帰ってきたらOrganizerが開いていてそこからExportして、ステージング用にArchiveを始めて…
ときにはOrganizerが開いたことに気付かずいつの間にかビルドが終わっていた、なんてこともしばしば。

CLIでコマンドを一つ叩くだけでビルドからファイル化、アップロードまでを自動化をすることでそれらを解決する、それがfastlaneなのです。

fastlaneで自動化へ

ゴール

今回はiOSをターゲットとし、プロジェクトディレクトリ直下のDeploy配下に、[project-name].ipaファイルを作成する環境を作成することをゴールにします。

fastlaneを使用すれば、Firebaseと接続しApp DistributionやAWS S3の特定ディレクトリへのアップロードまで自動化が可能です。
scp等を使用して会社で管理されているサーバーにアップロードする等も実現できます。
これについては今後の記事でお話させていただければと思います。

前提

Xcodeがインストールされていること

導入

fastlane.tools

弊社プロダクトでは、fastlaneを利用しています。
導入方法をざっくりと説明すると下記の5ステップ。

  1. rubyrubygemsをインストール
  2. rubygemsを使ってbundlerをインストール
  3. bundle initをし、Gemfileを生成
  4. Gemfilegem 'fastlane'を追記
  5. bundle installでfastlaneをインストール

これでプロジェクトディレクトリで fastlaneコマンドが使えるようになります。
bundlerでインストールをしたため、今後はbundle exec fastlane 〜というコマンドになります。

Xcodeを認識させる xcode-install

自動化ビルドを進めるにあたって、XcodeのGUIを使用しないようには出来ますが、 ビルドにはxcodebuildというXcodeコマンドが必要になります。Command Line Toolsと呼ばれております。
なので、fastlaneにCommand Line Toolsを認識させるためのライブラリもインストールしておきます。
Gemfilegem 'xcode-install'を追記し、再度bundle installをターミナルで打ちます。
このライブラリは、fastlaneの設定ファイルを編集するときに使用します。

実際に環境を作る

bundle exec fastlane init
とコマンドを打つとこのような表記が出ます。

fastlane can help you with all kinds of automation for your mobile app
We recommend automating one task first, and then gradually automating more over time
What would you like to use fastlane for?
1. 📸  Automate screenshots
2. 👩‍✈️  Automate beta distribution to TestFlight
3. 🚀  Automate App Store distribution
4. 🛠  Manual setup - manually setup your project to automate your tasks

上から

  1. スクリーンショットの自動化
  2. ベータ版やTestFlightへの自動アップロード
  3. App Storeへの自動アップロード
  4. 自分で設定する

となっています。今回は 4. を選びます。

いろいろなことが流れますが、すべてEnterで問題ありません。
以下は内容を意訳したものです。

新しいファイル`fastlane/Fastfile`と`fastlane/Appfile`を作成しました、gitに追加すればチーム全員がfastlaneの恩恵を受けることができます。
fastlaneでは「Fastfile」を使って自動化設定が保存できます。
スクリーンショットやコードサイニング、新しいリリースの作成などの様々な異なるタスクを自動化するために存在します。
お好みのエディタで作成されたFastlaneを開いてみてください。
利用可能なレーンやアクションを編集し、自分のニーズに合わせてカスタマイズすることが出来るようになりました。
利用可能なアクションを学びたい場合、https://docs.fastlane.tools/actions にアクセスしてください。

スクリーンショット自動化については
https://docs.fastlane.tools/getting-started/ios/screenshots/
ベータ版のアップロードについては
https://docs.fastlane.tools/getting-started/ios/beta-deployment/
App Storeへのリリースについては
https://docs.fastlane.tools/getting-started/ios/appstore-deployment/
コードサイニングについては
https://docs.fastlane.tools/codesigning/getting-started/
を参照してください。

最初にあるとおり、今後は fastlane/Fastfileを編集して、自動化タスクを作成していきます。
ここからは実際のサンプルを提示しながら進めていきます。

laneの作成

bundle exec fastlane initをした直後のFastfileには以下のような記述があります。

platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane do
    # add actions here: https://docs.fastlane.tools/actions
  end
end

ターミナルで bundle exec fastlane [lane_name] と打ったときの lane_name となるのが、上記で言うところの custom_lane の部分になります。
# add actions here: https://docs.fastlane.tools/actions となっているネスト内に書かれたアクションを記入していきます。
これで、記入されたアクションがbundle exec fastlane custom_laneのコマンドを打つことで自動的に走るようになります。
この lane: 〜 end を増やすことで、コマンドの種類を増やすことができます。

platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane_1 do
    # add actions here
  end

  lane :custom_lane_2 do
    # add actions here
  end

  lane :custom_lane_3 do
    # add actions here
  end
end

とすることで、

bundle exec fastlane custom_lane_1
bundle exec fastlane custom_lane_2
bundle exec fastlane custom_lane_3

のコマンドが認識されるようになります。

Xcodeのバージョンを指定する

前述した手順でxcode-installというライブラリをインストールしています。

xcversion(version: "14.1")

このように記述することで、fastlaneにCommand Line Toolsを認識させることができます。
versionを指定することでどのXcodeでビルドを行うかを指定することが可能です。

アプリケーションのビルドやArchiveを一括対応するアクション gym

gym()メソッドにいろいろなパラメータを与えることで、アプリケーションのビルドやArchiveをすべて自動で行ってくれる頼もしいアクションです。
ビルドの自動化という要件は、このアクションを使うことでほぼ完遂できると言っても過言ではないでしょう。

docs.fastlane.tools

公式ページには使用できるパラメータ等が網羅されています。コンパクトにまとめたサンプルがこちらです。

gym(
  # ターゲットとなるworkspace
  # 省略するとカレントディレクトリの.xcodeprojファイルを参照する
  workspace: "MyApp.xcworkspace", 
  # Build Configrationを指定
  configuration: "Debug", 
  # プロジェクトのSchemeを指定
  scheme: "MyApp", 
   # 出力先 dsymやxarchiveファイルもここにまとめて出力される
  output_directory: "path/to/dir",
  # 出力バイナリのファイル名 iOSの場合は.ipaを拡張子にする
  output_name: "my-app.ipa", 
  # Organizerでdistributionする際に指定するメソッド
  # 省略するとapp-store(ストア向き)の出力方法に切り替わる
  export_method: "enterprise"
)

これを先程の # add actions here: https://docs.fastlane.tools/actions 部分に挿入します。

platform :ios do
  desc "Description of what the lane does"
  lane :custom_lane do
    gym(
        workspace: "MyApp.xcworkspace",
        configuration: "Debug",
        scheme: "MyApp",
        output_directory: "deploy", # deployに変更
        output_name: "my-app.ipa",
        export_method: "enterprise"
    )
  end
end

こうすることで、

  • ワークスペースがMyApp.xcworkspace
  • SchemeがMyApp
  • Build ConfigurationがDebug
  • 出力方法はenterprise
  • 出力ディレクトリがdeploy
  • 出力ファイル名がmy-app.ipa

のビルドが自動的に行われ、ファイルが出力されます。🎉

また、export_optionsというキーを指定することで、ProvisioningProfileを指定することもできます。

export_options: {
    # Organizerでdistributionする際に指定するメソッド
    export_method: "enterprise",
    # 発行しているProvisioningProfile名
    # Apple Developerで確認できる名前でOK
    provisioningProfiles: "ProvisioningProfile Name"
}

TIPS

使用できるコマンドを確認する

laneに追加したコマンドの内容はfastlane/README.mdにまとまっています。
Fastfileを書き換えたのちbundle exec fastlane関連のコマンドを打つことで、fastlane側でFastfileから自動で生成されます。
descのキーで指定されている文字列もここに表示されます。

また、 bundle exec fastlane とコマンドで打つことで、コマンドを対話的に指定することも可能です。
その際にもコマンドの内容やdescで指定した文字列が表示されます。

複数環境を同時にビルドするには

laneの中で複数回gymをコールしてもいいのですが、Fastfileはrubyで解釈されるためrubyの記述に倣うことでサブルーチンなどを作成することもできます。

以下の例ではBuild Configurationで環境が切り替わるようになっていることが前提条件になっています。
コメントアウト部分を切り替えて環境を切り替えるタイプの場合は対応していないので、適宜実装を組み替えてください。

ステージング/本番の2環境の各ビルドと2環境同時ビルドを実現するFastfileを書いて、この記事を締めとさせていただきます。

# 本番環境向けのipaを作成する
bundle exec fastlane release_prod

# ステージング環境向けのipaを作成する
bundle exec fastlane release_stg

# 本番/ステージング環境向けのipaを同時に作成する
bundle exec fastlane release_multi
default_platform(:ios)
xcversion(version: "14.1") # Xcodeバージョンは適宜書き換える

WORKSPACE_NAME = "MyApp"
SCHEME_NAME = "MyApp"

# Build Configurationを記入する
module Configuration
    PRODUCTION = "Release"
    STAGING = "Staging"
end

platform :ios do
    desc "release for Production"
    lane :release_prod do
        build(Configuration::PRODUCTION)
    end

    desc "release for Staging"
    lane :release_stg do
        build(Configuration::STAGING)
    end

    desc "release for Staging/Production"
    lane :release_multi do
        build(Configuration::PRODUCTION)
        build(Configuration::STAGING)
    end
end

def build(configuration = Configuration::PRODUCTION)
    # deploy/Release と deploy/Staging のディレクトリ配下に出力
    output_directory = "deploy/#{configuration}/" 
    # MyApp-Release と MyApp-Stagingというファイル名で出力
    output_name = "#{SCHEME_NAME}-#{configuration}"
    gym(
        workspace: "#{WORKSPACE_NAME}.xcworkspace",
        configuration: configuration,
        scheme: "#{SCHEME_NAME}",
        output_directory: output_directory,
        output_name: "#{output_name}.ipa",
        export_method: "enterprise"
    )
end