fastlane(ファストレーン)は、iOS・Androidアプリのビルド、コード署名、テスト、TestFlight・App Store・Google Playへの配信を、Fastfileに書いた手順(lane)として1コマンドで実行するRuby製のオープンソースツールです。現行版は2026年10月15日公開の2.241.1で、2.241.0からRuby 3.2以上が必須になりました。9月までの解説にある「Ruby 3.1以上」はもう通りません。この記事では、インストールからFastfileの書き方、APIキー認証、matchによる証明書の共有、各ストアへの配信、Flutterでの置き場所、CIへの載せ方までを説明します。設定例は2.241.1(Ruby 4.0.6)のfastlane lanesで解析が通ることを確認したものです。実アプリのビルド・署名・ストア配信までは実行していません。
なお、同じ綴りの「Cisco Fastlane」(Wi-Fiで業務アプリの通信を優先するCiscoとAppleの機能)や「au 5G Fast Lane」(KDDIの5G優先通信サービス)、Fastlane Japan株式会社は別物です。この記事はアプリ開発ツールのfastlaneを扱います。
まとめ:fastlaneで押さえる要点
- 役割:ビルド(gym)、署名(match)、テスト(scan)、TestFlight配信(pilot)、App Store提出(deliver)、Google Play配信(supply)をlaneにまとめ、
bundle exec fastlane betaのように実行する。 - 導入:Ruby 3.2以上が必須(2.241.0から)。公式の推奨はGemfile+Bundlerで版を固定する方法で、macOS標準のRuby 2.6は使えない。
- 認証:App Store Connect APIのチームキー(key_id・issuer_id・.p8)を使えば2要素認証なしでCIから動く。個人キーではmatchのプロファイル作成ができない。
- 落とし穴:supplyのtrackは既定がproduction、matchのreadonlyは既定がfalse。指定を忘れると本番公開や証明書の新規作成が起きる。
- 向かない場面:リリースが年数回の個人開発や、iOSだけでXcode Cloudの月25時間に収まるチームは、Ruby環境を足さない既存の運用を続ける。
fastlaneの役割とアクション名の対応
fastlaneは「アクション」と呼ばれる部品を並べてlaneを作ります。gymやdeliverは独立したツールだった時代の名前で、現在は機能名のアクション(build_appなど)の別名です。fastlane action gymを実行すると「Alias for the build_app action」と表示されます。どちらで書いても動きますが、Fastfileを初めて読む人には機能名の方が通じます。
| 別名(旧ツール名) | アクション名 | 処理内容 |
|---|---|---|
| gym | build_app / build_ios_app | ビルドと署名、.ipaとdSYMの生成 |
| scan | run_tests | シミュレータ・実機でテスト実行 |
| match | sync_code_signing | 証明書とプロファイルをチームで共有 |
| pilot | upload_to_testflight | TestFlightへのアップロードとテスター管理 |
| deliver | upload_to_app_store | メタデータ・スクショ・バイナリの提出 |
| snapshot | capture_ios_screenshots | 多言語・多端末のスクショ自動撮影 |
| supply | upload_to_play_store | Google PlayへのAAB・メタデータ配信 |
ソースはGitHubのfastlane/fastlaneで、MITライセンスです。Googleが運営していた時期がありますが、2023年10月にMobile Native Foundationへの移管が承認されています。
fastlaneのインストール手順(Ruby 3.2以上・Bundler・Homebrew)
Ruby 3.2が必須になった経緯とmacOS標準Rubyの扱い
RubyGemsに登録された2.241.1のrequired_ruby_versionは>= 3.2.0です。要件は短い間隔で上がっており、2.238.0までは3.0以上、2.239.0(2026年9月4日)で3.1以上、2.241.0のリリースノート(2026年10月10日)に「Ruby 3.2 is now the minimum (dropping Ruby 3.1)」とあります。Ruby 3.1の環境でbundle update fastlaneを実行すると、2.240.1より上には上がりません。
一方、macOS 26.6.2の/usr/bin/rubyは2.6.10のままです。この環境で/usr/bin/gem install fastlaneを実行すると、fastlane本体より先に依存gemの段階で止まります(2.240.1で確認)。
ERROR: Error installing fastlane:
pp requires Ruby version >= 2.7.0. The current ruby version is 2.6.10.210.
システムRubyはgemの導入にsudoが要り、公式docsも推奨していません。Homebrew・rbenv・miseなどでRubyを用意します。公式のセットアップ手順は「3.2以上に対応、3.3以上を推奨」と書いているので、新規導入なら3.3以上を選びます。rbenvでの版の切り替えはrbenvとは?Rubyバージョン管理の仕組みとRVMとの違い・1.3系の導入手順で説明しています。
Gemfile+Bundlerによるバージョン固定(推奨)
公式docsが推奨するのは、プロジェクト直下のGemfileでfastlaneの版を宣言し、Bundler経由で実行する方法です。開発者ごと・CIごとに版がずれず、起動も速くなります。
source "https://rubygems.org"
gem "fastlane", "~> 2.241"
~> 2.241は「2.241以上・3.0未満」を許す指定です。実際に使う版はGemfile.lockで固定され、bundle installでは変わらず、bundle update fastlaneやbundle update --allで依存関係を解決し直したときに上がります。
bundle install
bundle exec fastlane lanes # 定義済みのlane一覧
bundle update fastlane # fastlaneと必要な依存gemを更新
GemfileとGemfile.lockは両方ともGitに入れ、CIでは最初のステップでbundle installを実行します。2.241.0からは実行のたびに冒頭へ「fastlane 2.241.1 (Ruby 4.0.6, gem)」のように版・Ruby・導入元が表示されるので、CIのログでどの版が動いたかを後から確かめられます。Gemfileを使わずに起動すると「Get started using a Gemfile for fastlane」と案内が出ます。Bundler自体の使い方はgemとBundlerの使い方|Bundler 4系で変わったコマンドとGemfileの書き方にまとめています。
Homebrew経由の導入とチーム利用の制約
1人で試すだけならbrew install fastlaneでも動きます。2026年10月24日時点でHomebrewのformulaは2.241.1で、HomebrewのRubyに依存するためRubyを別に用意する必要がありません。ただしチームでは版がそろわず、プラグインもFastfileと別の場所に入るため、共有プロジェクトではGemfile方式に寄せます。
ロケールがUTF-8でないとビルドやアップロードで失敗するため、公式docsはシェル設定にexport LC_ALL=en_US.UTF-8とexport LANG=en_US.UTF-8を追加するよう求めています。
fastlane initとFastfile・Appfileの書き方
fastlane initの4つの選択肢
Gemfileを置いたXcodeプロジェクトのディレクトリでbundle exec fastlane initを実行すると、用途を4つから選びます。
- Automate screenshots(スクリーンショット撮影)
- Automate beta distribution to TestFlight(TestFlight配信)
- Automate App Store distribution(App Store配信。既存のメタデータを取り込む)
- Manual setup(Fastfileの雛形だけを作る)
どれを選んでもfastlane/Fastfileとfastlane/Appfileが作られ、後から自由に書き換えられます。1〜3はApple IDでのログインを求めるため、後述のAPIキーを使う予定なら4のManual setupで雛形だけ作る方が手戻りがありません。
Fastfileでlaneを定義する例
次のFastfileは、テスト・TestFlight配信・App Store提出・Google Play内部テストの4つのlaneを持つ例です。MyAppなどの仮名を置き換え、環境変数に認証情報を入れ、matchの保存先とAndroidのリリース署名を設定してから実行します。
default_platform(:ios)
platform :ios do
before_all do |lane|
next if lane == :test
app_store_connect_api_key(
key_id: ENV["ASC_KEY_ID"],
issuer_id: ENV["ASC_ISSUER_ID"],
key_content: ENV["ASC_KEY_CONTENT"],
is_key_content_base64: true
)
end
desc "ユニットテストを実行"
lane :test do
run_tests(scheme: "MyApp")
end
desc "TestFlightへ配信"
lane :beta do
sync_code_signing(type: "appstore", readonly: is_ci)
increment_build_number(build_number: latest_testflight_build_number + 1)
build_app(scheme: "MyApp")
upload_to_testflight(skip_waiting_for_build_processing: true)
end
desc "App Storeへ提出"
lane :release do
sync_code_signing(type: "appstore", readonly: is_ci)
increment_build_number(build_number: latest_testflight_build_number + 1)
build_app(scheme: "MyApp")
upload_to_app_store(
submit_for_review: true,
automatic_release: false,
force: true,
precheck_include_in_app_purchases: false
)
end
end
platform :android do
desc "Google Playの内部テストへ配信"
lane :internal do
gradle(task: "bundle", build_type: "Release")
upload_to_play_store(
track: "internal",
package_name: "com.example.myapp",
json_key: ENV["PLAY_JSON_KEY_PATH"]
)
end
end
実行はbundle exec fastlane ios betaです。default_platform(:ios)があるのでbundle exec fastlane betaでも同じlaneが走ります。before_allはiOSのlaneの前にだけ呼ばれ、Androidのlaneには適用されません。next if lane == :testで、ストアに接続しないテストのlaneではAPIキーを読み込まないようにしています。readonly: is_ciは、CIでは既存の証明書を取り出すだけにし、CI以外では新規作成を許す書き方です。管理者かどうかは判定しないため、新規作成を管理者に限定するには認証情報へのアクセスを別途制限します。
ビルド番号の重複を避けるため、上の例ではTestFlight上の最新番号に1を足しています。ただし、複数ジョブが同時に同じ番号を取得すると重複するため、この方式では同じアプリの配信ジョブを直列に実行します。increment_build_numberは内部でagvtoolを呼びますが、build_numberを明示する場合、公式仕様ではApple Generic Versioningの有効化は必須ではありません。
Appfileに書く共通設定
Appfileには、各アクションが共通で参照するアプリ識別子やチームIDを書きます。
app_identifier("com.example.myapp")
team_id("ABCDE12345")
Apple IDで認証する場合だけapple_id("[email protected]")を足します。APIキー認証ならApple IDは不要です。
.gitignoreに入れる生成ファイル
Fastfile・Appfile・Gemfileはリポジトリに入れ、実行のたびに生成されるファイルは除外します。公式のソース管理ガイドが挙げているのは次の4つです。
# fastlane specific
**/fastlane/report.xml
# deliver temporary files
**/fastlane/Preview.html
# snapshot generated screenshots
**/fastlane/screenshots
# scan temporary files
**/fastlane/test_output
APIキーの.p8やGoogle PlayのサービスアカウントJSONは、この4行に含まれていません。リポジトリの外に置くか、CIのシークレットから渡します。
App Store Connect APIキーによる認証
公式docsのAPIキーの説明が推奨する認証方式です。2要素認証を通さずに済むため、CIのように人が画面を見られない環境でも止まりません。App Store Connectの「ユーザーとアクセス」でキーを発行し、次の値をapp_store_connect_api_keyに渡します。
| パラメータ | 環境変数 | 要否・既定値 |
|---|---|---|
| key_id | APP_STORE_CONNECT_API_KEY_KEY_ID | 必須 |
| issuer_id | APP_STORE_CONNECT_API_KEY_ISSUER_ID | チームキーで必須 |
| key_filepath | APP_STORE_CONNECT_API_KEY_KEY_FILEPATH | key_contentと択一 |
| key_content | APP_STORE_CONNECT_API_KEY_KEY | key_filepathと択一 |
| is_key_content_base64 | APP_STORE_CONNECT_API_KEY_IS_KEY_CONTENT_BASE64 | 既定false |
| duration | APP_STORE_CONNECT_API_KEY_DURATION | 既定500秒・上限1200秒 |
キーはチームキーで作ります。個人キーはプロビジョニング関連のAPIを使えないため、matchで証明書やプロファイルを作る処理が通りません。issuer_idは個人キーのときだけnilにします。
.p8は一度しかダウンロードできません。CIでは.p8の中身をBase64にしてシークレットへ入れ、is_key_content_base64: trueで渡すと改行の崩れを避けられます。.p8として読めない文字列をkey_contentに渡すと、2.241.1では次のエラーで止まりました。
spaceship/lib/spaceship/connect_api/token.rb:76:in 'OpenSSL::PKey::EC#initialize': [!] invalid curve name (OpenSSL::PKey::PKeyError)
このエラーが出たら、まずシークレットの改行とBase64の指定を疑います。
APIキーに対応していないツールも残っています。公式の対応表では、アプリをApp Store Connectに新規作成するproduceと、プッシュ通知証明書を作るpemが「No」です。2.241.0でproduceの一部がAPIキーに対応しましたが、2.241.1で差し戻されました。これらだけはApple IDで実行し、CIではfastlane spaceauth -u [email protected]で発行したセッションをFASTLANE_SESSIONに入れて使います。
match(sync_code_signing)による証明書の共有
matchの保存先・暗号化・readonly設定
matchは、配布用の証明書とプロビジョニングプロファイルを1か所に暗号化して保存し、チーム全員とCIが同じものを取り出す仕組みです。個人のMacで作った証明書を手渡しする運用をやめられます。署名の仕組みそのものはプロビジョニングプロファイルとは|iOS署名の仕組み・4種類・作成・期限・エラー対処で扱っています。
- type:appstore、adhoc、development(既定)、enterprise、developer_idなど。TestFlight・App Store向けはappstore。
- storage_mode:git(既定)、google_cloud、s3、gitlab_secure_filesの4種類。
- MATCH_PASSWORD:保存先がgitのときに証明書を暗号化・復号するパスフレーズ。紛失すると取り出せない。2.241.1のソースではs3も既定で同じ暗号化を使い、google_cloudとgitlab_secure_filesでは使わない。
- readonly:既定はfalse。trueにすると既存の証明書を取り出すだけで新規作成しない。
CIでは必ずreadonlyをtrueにします。既定のfalseでは、保存先に無い証明書やプロファイルをmatchが新規作成します。matchの公式docsも「CIでは常にreadonlyモードを使う」ことを推奨しています。新規作成は管理者が手元でfastlane match appstoreを実行するときだけにします。
matchへの既存証明書の取り込みと発行上限への対処
matchを後から入れるチームでは、Apple Developerアカウントにすでに配布用証明書があります。matchに新しく作らせると、アカウントで作れる配布用証明書の数の上限に当たることがあります。Appleが「You already have a current」で始まるエラーを返すと、fastlaneは次のメッセージで止まります(2.241.1のcertのソースより)。
Could not create another Distribution certificate, reached the maximum number of available Distribution certificates.
対処は2つです。
- 既存の証明書を取り込む:
fastlane match importを実行し、証明書(.cer)、秘密鍵(.p12)、プロファイルのパスを指定する。matchはDeveloper Portalで証明書を照合してから暗号化して保存する。秘密鍵が手元に無い証明書は取り込めない。 - まとめて失効させて作り直す:
fastlane match nuke distributionで配布用の証明書とプロファイルを失効させ、matchで作り直す。公式docsによれば、App StoreやTestFlightにすでに出ているアプリは動き続けるが、Ad HocとEnterpriseで配ったビルドは使えなくなる。
Ad HocやEnterpriseで配布中のビルドがあるならimportを選びます。nukeは秘密鍵が誰の手元にも残っていない場合の最後の手段です。
TestFlightとApp Storeへの配信(pilot・deliver)
pilot(upload_to_testflight)によるTestFlight配信
pilotはビルド済みの.ipaをApp Store Connectへアップロードし、TestFlightのテスター管理も担います。アップロード後、Apple側でビルドの処理が終わるまで既定では待ち続けます。CIの実行時間を節約するならskip_waiting_for_build_processing: trueで待たずに終了させ、外部テスターへの配布は処理完了後に行います。
2.241.0からは、同じlaneでbuild_appが作った.ipaを優先してアップロードします。それまでは現在のディレクトリにある最も新しい.ipaが選ばれることがあり、古い成果物が残っていると別のビルドが上がる恐れがありました。upload_to_app_storeも同じ変更を受けています。
deliver(upload_to_app_store)による審査提出
deliverはメタデータ、スクリーンショット、App Preview、バイナリをApp Store Connectへ送ります。既定の挙動は次のとおりで、何も指定しないと審査には出しません。
| オプション | 既定値 | 用途 |
|---|---|---|
| submit_for_review | false | アップロード後に審査へ提出 |
| automatic_release | 未指定 | 承認後に自動公開するか |
| skip_metadata | false | 説明文などの送信を省く |
| skip_screenshots | false | スクショの送信を省く |
| run_precheck_before_submit | true | 提出前にprecheckで規約違反語を検査 |
| force | false | HTMLプレビュー確認を省く |
deliverは確認用のHTMLプレビューを開き、「Does the Preview … look okay for you?」とy/nを尋ねます。対話できないCIでは「Could not retrieve response as fastlane runs in non-interactive mode」で失敗するため、force: trueを付けます。オプションはfastlane/Deliverfileに書いておくこともできます。
APIキーで認証している場合は、precheck_include_in_app_purchases: falseも必要です。既定のtrueのままだと、提出前のprecheckが「Precheck cannot check In-app purchases with the App Store Connect API Key (yet)」で止まります。省かれるのはアプリ内課金の文言チェックだけなので、課金アイテムの説明文は提出前に人が確認します。
supply(upload_to_play_store)によるGoogle Play配信
AndroidではsupplyがAABやAPK、ストア掲載情報をGoogle Playへ送ります。認証にはGoogle CloudのサービスアカウントのJSONキーをjson_keyで渡します。2.241.1ではJSONの中身をjson_key_dataで直接渡す方法や、Application Default Credentialsも使えます。配信先のアプリはpackage_name(AndroidのapplicationId)で指定し、Appfileにpackage_name("...")と書いておくこともできます。
注意したいのはtrackの既定値です。upload_to_play_storeの公式docsでは、指定しなければproductionになります。社内検証のつもりで素のupload_to_play_storeを呼ぶと本番トラックに載るため、上のFastfile例のようにtrack: "internal"を必ず明示します。段階的公開はrolloutに0〜1の割合(例:0.1で10%)を渡します。
Firebase経由でテスターに配る場合は、fastlane add_plugin firebase_app_distributionでプラグインを追加します。追加したプラグインはfastlane/Pluginfileに記録され、Gemfileから読み込まれます。配布先の設計はFirebase App Distributionとは|配信物の分岐とテスター名簿・CI組み込みの設計【2026年8月時点】で説明しています。
FlutterやReact Nativeのプロジェクトでfastlaneを使う手順
クロスプラットフォームのプロジェクトでは、fastlaneをリポジトリの直下ではなく、iosとandroidのディレクトリにそれぞれ置きます。Flutter公式の継続的デリバリーの手順(2026年7月31日更新・Flutter 3.47)は次の順序を示しています。
flutter build appbundleとflutter build ipaでリリースビルドが通ることを確かめる。[project]/androidと[project]/iosでそれぞれfastlane initを実行する。Gemfileも両方のディレクトリに置く。- リリースのたびに
flutter buildを先に実行し、cd ios(またはcd android)してからbundle exec fastlane <lane名>を実行する。
Android側はflutter buildが作ったAABを使うので、upload_to_play_storeのaabに../build/app/outputs/bundle/release/app-release.aabを指定します。iOS側でfastlaneのbuild_appに署名とビルドを任せる場合、CIではflutter build ios --release --no-codesign --config-onlyで設定ファイルだけを生成してからlaneを呼びます。React Nativeもiosとandroidのディレクトリを持つ構成なので、同じ置き方になります。Expo(EAS)やCodemagicでビルドと提出を済ませているなら、fastlaneを重ねる必要はありません。
CI/CD組み込み時のキーチェーン・認証・Xcode設定
fastlaneはCIのジョブからbundle exec fastlane betaを呼ぶだけで動きますが、手元と違ってキーチェーン、認証、Xcodeの版を決めておく必要があります。
- setup_ci:一時キーチェーン(既定名fastlane_tmp_keychain)を作り、matchの証明書をそこへ入れる。CI以外では「Not running on CI」と表示して何もしない。
- 認証:APIキーをシークレットに置き、Apple IDの2要素認証を経由しない。2.241.0からは、オプションに秘密と印の付いた値がfastlaneのログ上で伏せ字になる。
- Xcodeの版:Appleの要件により、2026年4月28日以降にApp Store Connectへ上げるアプリはXcode 26以降・iOS 26 SDKでのビルドが必須。2026年10月15日にXcode 27.1が出ており、ランナーの既定Xcodeはイメージ更新で変わるため、
xcode-selectで使う版を明示する。確認と切り替えはXcodeの最新バージョンは27|確認・アップデート手順とIntel Macは26.6までを参照。
GitHub Actionsでのワークフロー定義、ランナーのイメージ選び、CIでだけ起きるエラー(キーチェーンのロックやmulti_jsonの読み込み失敗など)はGitHub Actionsでfastlaneを動かすiOSリリース自動化|設定とCI固有エラー対処で手順ごとに説明しています。Macを持たずにビルドと提出を回す構成はWindowsでiOS・iPhoneアプリを開発する方法|Macなしでビルドと提出を回す4経路と手順で比べています。リリース工程の自動化をCI/CDの整備ごと進めたい場合は、DevOps・CI/CD導入支援でも相談を受けています。
fastlaneを導入しない方がよい場面
fastlaneはRubyの版、gemの依存、Appleの仕様変更への追随という保守コストを抱えます。2026年9月4日の2.239.0から10月10日の2.241.0までの約5週間でRubyの最低要件が3.0から3.2まで2段上がったように、Ruby側の変化に合わせた更新は今後も続きます。次の条件に当てはまるなら、導入を見送る方が合理的です。
- リリースが年に数回で開発者が1人:Xcodeの「Archive」から「Distribute App」で必要な配信を完結でき、繰り返す手作業も少ないなら、Ruby環境を足す前に手動運用を続ける。
- Xcode Cloudで足りる:Apple Developer Programの会員には月25時間の計算時間が含まれ、署名とTestFlight配信をApple側が担う。iOSだけのアプリで、ビルドがこの枠に収まるなら追加の仕組みは要らない。
- ExpoやFlutterのクラウドビルドを使っている:EAS SubmitやCodemagicの配信機能と役割が重なる。二重に持つと、どちらの設定が効いているかの切り分けが難しくなる。
逆に、iOSとAndroidを同じ手順で出したい、ストアの説明文やスクリーンショットを多言語でGit管理したい、という条件があるならfastlaneが候補になります。複数アプリのビルドと配信だけならXcode Cloudでも扱えるため、判断の分かれ目はAndroid配信とストアメタデータの管理まで1つの仕組みにまとめたいかどうかです。
よくある質問
fastlaneの読み方と「fast lane」の意味は?
読み方は「ファストレーン」です。英語のfast laneには、高速道路の追い越し車線という意味があります。
fastlaneは無料で使えますか?
MITライセンスのオープンソースで、fastlane自体は無料です。ただしApp Store Connectへの配信にはApple Developer Programの年会費(99ドル)が、Google Playへの配信にはGoogle Play Consoleの登録料が別途かかります。年会費の中身はApple Developer Programとは?年会費99ドル(アプリ経由12,800円)の中身・登録方法・ログイン先で説明しています。
fastlaneのアップデート方法は?
Gemfileで管理している場合はbundle update fastlaneを実行し、更新されたGemfile.lockをコミットします。Homebrewで入れた場合はbrew upgrade fastlaneです。2.241.0以降はRuby 3.2以上が必要なので、Ruby 3.1以下の環境では先にRubyを上げます。
pilotとdeliverの違いは?
pilotはTestFlight向けで、ビルドのアップロードとテスター管理を担います。deliverはApp Store向けで、メタデータ・スクリーンショットの更新と審査提出を担います。審査に出す前の社内配布はpilot、公開はdeliverと使い分けます。
fastlaneはAndroidアプリでも使えますか?
使えます。gradleアクションでビルドし、supply(upload_to_play_store)でGoogle Playへ配信します。Android用のスクリーンショット撮影にはscreengrabがあります。iOSと同じFastfileにplatform :androidブロックを並べて書けます。