モバイルアプリの開発では、ビルド、テスト、署名、ストアへのアップロードといった一連のリリース作業が複雑で時間がかかります。Webアプリケーションと異なり、コード署名やProvisioning Profileの管理、App Store ConnectやGoogle Play Consoleとの連携など、モバイル特有のハードルが存在します。
こうした煩雑な作業を自動化するツールとして、Fastlaneは業界標準の地位を確立しています。筆者のチームでは、Fastlane導入前は1回のリリースに半日以上かかっていたものが、導入後は30分程度で完了するようになりました。本記事では、Fastlaneを使ったモバイルCI/CDの構築方法を実践的に解説します。
Fastlaneの導入は非常にシンプルです。まず、Rubyのgemとしてインストールします。
gem install fastlane
プロジェクトのルートディレクトリで初期化コマンドを実行すると、対話形式で基本設定が行われます。
fastlane init
初期化が完了すると、fastlaneディレクトリが作成され、その中にAppfileとFastfileが生成されます。AppfileにはアプリのBundle IDやApple IDなどの基本情報を記載します。
# Appfile
app_identifier("com.example.myapp")
apple_id("developer@example.com")
team_id("ABCD1234EF")
FastfileはFastlaneの中核となる設定ファイルで、自動化のワークフロー(レーン)を定義します。以下は、iOSアプリの基本的なレーン構成例です。
default_platform(:ios)
platform :ios do
desc "テストを実行する"
lane :test do
scan(
scheme: "MyApp",
devices: ["iPhone 15"],
clean: true
)
end
desc "TestFlightにベータ版を配布する"
lane :beta do
increment_build_number
build_app(
scheme: "MyApp",
export_method: "app-store"
)
upload_to_testflight(
skip_waiting_for_build_processing: true
)
end
desc "App Storeにリリースする"
lane :release do
build_app(
scheme: "MyApp",
export_method: "app-store"
)
upload_to_app_store(
force: true,
submit_for_review: true
)
end
end
各レーンはfastlane test、fastlane betaのようにコマンドラインから実行できます。
Androidアプリの場合は、以下のようにGradle連携とGoogle Play Consoleへのアップロードを設定します。
platform :android do
desc "テストを実行する"
lane :test do
gradle(
task: "test"
)
end
desc "内部テストトラックに配布する"
lane :beta do
gradle(
task: "bundle",
build_type: "Release"
)
upload_to_play_store(
track: "internal",
aab: "app/build/outputs/bundle/release/app-release.aab"
)
end
end
iOSアプリ開発で最も厄介な問題の一つがコード署名管理です。Fastlaneのmatchを使えば、証明書とProvisioning Profileをチーム全体で安全に共有できます。
# Matchfile
git_url("https://github.com/your-org/certificates.git")
storage_mode("git")
type("appstore")
app_identifier("com.example.myapp")
初回セットアップでfastlane match appstoreを実行すると、証明書が生成され、指定したGitリポジトリに暗号化して保存されます。以降、チームメンバーは同じコマンドで証明書を取得できるため、「自分の環境ではビルドできるのに」という問題が解消されます。
Fastlaneは主要なCIサービスと容易に連携できます。以下はGitHub Actionsでの設定例です。
name: iOS CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Run tests
run: bundle exec fastlane test
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Deploy to TestFlight
run: bundle exec fastlane beta
env:
APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_API_KEY }}
PRでは自動テスト、mainブランチへのマージ時にはTestFlightへの自動配布が行われます。
GemfileでFastlaneのバージョンを固定し、bundle exec fastlaneで実行することで、チーム間のバージョン差異を防ぎますerrorブロックでビルド失敗時の通知やクリーンアップ処理を定義しておきますFastlaneを使ったモバイルCI/CDは、初期構築にある程度の工数がかかりますが、一度整備すれば開発チームの生産性を劇的に向上させます。特に、コード署名管理の自動化とリリースプロセスの標準化は、チームの拡大に伴うスケーラビリティの確保にも貢献します。まずはテストの自動化から始め、段階的にデプロイまでパイプラインを拡張していくアプローチがおすすめです。