ガイド - 自動化

Fastlane + 専用 Mac サーバー: 完全自動化ガイド

専用 Mac Mini M4 サーバー上の Fastlane を使って、iOS のリリースプロセス全体 -- ビルド、コード署名、スクリーンショット、TestFlight へのデプロイ -- を自動化します。

読了時間 35 分 2026 年 3 月更新

1. なぜ専用 Mac で Fastlane なのか?

Fastlane は、iOS と Android の開発における標準的な自動化ツールです。コード署名から TestFlight へのデプロイまで、あらゆる処理を扱います。専用 Mac Mini M4 で Fastlane を実行すると、次のメリットが得られます。

永続的なキーチェーン

コード署名証明書が実行間で保持されます。ビルドのたびにインポート/エクスポートする必要がありません。

高速なインクリメンタルビルド

DerivedData が保持されるため、fastlane build が 15 分以上ではなく 2〜4 分で完了します。

シミュレーターのスクリーンショット

fastlane snapshot を実際のシミュレーターで実行し、すべてのデバイスサイズに対応します。

信頼性の高いデプロイ

安定した専用環境なら、不安定なデプロイやコード署名の問題が減ります。

2. Fastlane をインストールする

Mac Mini M4 に SSH で接続し、Fastlane をインストールします。最もシンプルなセットアップには Homebrew をおすすめします。

選択肢 A: Homebrew でインストールする(推奨)

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

# Install Fastlane
brew install fastlane

# Verify installation
fastlane --version
# fastlane 2.225.0

選択肢 B: RubyGems でインストールする

# Use the system Ruby or install rbenv for version management
gem install fastlane -NV

# Or with Bundler (recommended for team consistency):
# Create a Gemfile in your project root
cat > Gemfile <<'EOF'
source "https://rubygems.org"

gem "fastlane"
gem "cocoapods"  # if using CocoaPods
EOF

bundle install

プロジェクトで Fastlane を初期化する

# Navigate to your project directory
cd /path/to/your/ios-project

# Initialize Fastlane
fastlane init

# Choose option 4: "Manual setup"
# This creates the fastlane/ directory with Appfile and Fastfile

3. コード署名のために Match を設定する

Fastlane Match は、コード署名証明書とプロビジョニングプロファイルを、プライベートな Git リポジトリまたはクラウドストレージに保存します。これにより、すべてのマシン(およびチームメンバー)が同じ署名 ID を使えるようになります。

Match を初期化する

# Initialize match (choose "git" for storage)
fastlane match init

# This creates fastlane/Matchfile

Matchfile を設定する

# fastlane/Matchfile

git_url("https://github.com/your-org/ios-certificates.git")

storage_mode("git")

type("appstore")  # default type, can be overridden per lane

app_identifier(["com.yourcompany.myapp"])
username("your-apple-id@example.com")

# For CI environments, use App Store Connect API key instead of username/password
# api_key_path("fastlane/AuthKey.json")

証明書を生成する

# Generate development certificates and profiles
fastlane match development

# Generate App Store distribution certificates and profiles
fastlane match appstore

# For ad-hoc distribution
fastlane match adhoc

# On CI, use readonly mode to avoid accidentally creating new certs
fastlane match appstore --readonly

4. Fastfile を作成する(ビルド、テスト、デプロイのレーン)

iOS アプリのビルド、テスト、デプロイのためのレーンを含む、完全な Fastfile を示します。

# fastlane/Fastfile

default_platform(:ios)

platform :ios do

  # ---- SHARED ----

  before_all do
    setup_ci if ENV['CI']  # Configures keychain for CI environments
  end

  # ---- BUILD ----

  desc "Build the app for testing"
  lane :build do
    match(type: "development", readonly: true)

    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      configuration: "Debug",
      destination: "generic/platform=iOS Simulator",
      derived_data_path: "DerivedData",
      skip_archive: true,
      skip_codesigning: true
    )
  end

  # ---- TEST ----

  desc "Run all unit and UI tests"
  lane :test do
    run_tests(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      devices: ["iPhone 16 Pro"],
      derived_data_path: "DerivedData",
      result_bundle: true,
      output_directory: "fastlane/test_results",
      parallel_testing: true,
      concurrent_workers: 4
    )
  end

  # ---- BETA ----

  desc "Build and push a new beta to TestFlight"
  lane :beta do
    # Ensure we are on a clean git state
    ensure_git_status_clean

    # Fetch App Store certificates
    match(type: "appstore", readonly: true)

    # Increment build number
    increment_build_number(
      build_number: latest_testflight_build_number + 1
    )

    # Build the app
    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      export_method: "app-store",
      derived_data_path: "DerivedData",
      output_directory: "fastlane/builds"
    )

    # Upload to TestFlight
    upload_to_testflight(
      skip_waiting_for_build_processing: true,
      api_key_path: "fastlane/AuthKey.json"
    )

    # Commit the version bump
    commit_version_bump(
      message: "chore: bump build number [skip ci]",
      force: true
    )

    # Tag the release
    add_git_tag(
      tag: "beta/#{lane_context[SharedValues::BUILD_NUMBER]}"
    )

    push_to_git_remote
  end

  # ---- RELEASE ----

  desc "Build and submit to App Store Review"
  lane :release do
    match(type: "appstore", readonly: true)

    # Increment version number (patch)
    increment_version_number(bump_type: "patch")
    increment_build_number(
      build_number: latest_testflight_build_number + 1
    )

    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      export_method: "app-store",
      derived_data_path: "DerivedData"
    )

    upload_to_app_store(
      submit_for_review: true,
      automatic_release: false,
      api_key_path: "fastlane/AuthKey.json",
      precheck_include_in_app_purchases: false
    )

    commit_version_bump(message: "chore: release #{lane_context[SharedValues::VERSION_NUMBER]}")
    add_git_tag
    push_to_git_remote
  end

  # ---- ERROR HANDLING ----

  error do |lane, exception|
    # Send notification on failure (Slack, email, etc.)
    # slack(
    #   message: "Lane #{lane} failed: #{exception.message}",
    #   success: false
    # )
  end
end

5. スクリーンショットの自動化を設定する

Fastlane Snapshot は、複数のデバイスと言語にわたる App Store 用スクリーンショットを自動的に撮影します。専用 Mac では、リソースを奪い合うことなく安定して実行できます。

# Initialize snapshot
fastlane snapshot init

# This creates:
# - fastlane/Snapfile
# - fastlane/SnapshotHelper.swift (add to UI test target)

Snapfile を設定する

# fastlane/Snapfile

devices([
  "iPhone 16 Pro Max",
  "iPhone 16 Pro",
  "iPhone SE (3rd generation)",
  "iPad Pro 13-inch (M4)"
])

languages([
  "en-US",
  "fr-FR",
  "de-DE",
  "ja"
])

scheme("MyAppUITests")
output_directory("./fastlane/screenshots")
clear_previous_screenshots(true)

# Speed up by running in parallel
concurrent_simulators(true)

UI テストに Snapshot を追加する

// In your XCUITest file:
import XCTest

class ScreenshotTests: XCTestCase {

    override func setUp() {
        continueAfterFailure = false
        let app = XCUIApplication()
        setupSnapshot(app)
        app.launch()
    }

    func testHomeScreen() {
        snapshot("01_HomeScreen")
    }

    func testDetailScreen() {
        let app = XCUIApplication()
        app.cells.firstMatch.tap()
        snapshot("02_DetailScreen")
    }

    func testSettings() {
        let app = XCUIApplication()
        app.tabBars.buttons["Settings"].tap()
        snapshot("03_Settings")
    }
}

スクリーンショット用のレーンを追加する

  # Add to your Fastfile:
  desc "Capture App Store screenshots"
  lane :screenshots do
    capture_screenshots
    frame_screenshots(white: true)  # Add device frames
    upload_to_app_store(
      skip_binary_upload: true,
      skip_metadata: true,
      api_key_path: "fastlane/AuthKey.json"
    )
  end

6. TestFlight にデプロイする

CI 環境では、Apple ID の認証情報の代わりに App Store Connect API キーを使います。これにより、ヘッドレスサーバーでの 2FA プロンプトを回避できます。

API キーを作成する

  1. App Store Connect > Users and Access > Keys に移動します
  2. + ボタンをクリックして新しい API キーを生成します
  3. App Manager ロールを選択します
  4. .p8 ファイルをダウンロードします
  5. Key IDIssuer ID を控えておきます

API キーの JSON を作成する

# fastlane/AuthKey.json
{
  "key_id": "YOUR_KEY_ID",
  "issuer_id": "YOUR_ISSUER_ID",
  "key": "-----BEGIN PRIVATE KEY-----\nYOUR_P8_KEY_CONTENT\n-----END PRIVATE KEY-----",
  "in_house": false
}

# IMPORTANT: Add this to .gitignore!
echo "fastlane/AuthKey.json" >> .gitignore

デプロイを実行する

# Deploy to TestFlight
fastlane beta

# Or run the full release pipeline
fastlane release

7. CI/CD と連携する

Fastlane はあらゆる CI/CD プラットフォームとシームレスに連携します。ここでは、セルフホストの Mac Mini M4 ランナーを使った GitHub Actions の例を示します。

# .github/workflows/deploy.yml
name: Deploy to TestFlight

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: [self-hosted, macOS, ARM64, M4]

    env:
      MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
      MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_TOKEN }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up App Store Connect API Key
        run: |
          mkdir -p fastlane
          echo '${{ secrets.APP_STORE_CONNECT_API_KEY }}' > fastlane/AuthKey.json

      - name: Install dependencies
        run: |
          bundle install
          pod install  # if using CocoaPods

      - name: Deploy to TestFlight
        run: bundle exec fastlane beta

      - name: Clean up API key
        if: always()
        run: rm -f fastlane/AuthKey.json

8. ベストプラクティス

Fastlane のバージョン固定に Bundler を使う

バージョンを固定した Fastlane を含む Gemfile を追加します。bundle exec fastlane を実行して、すべての環境で一貫したバージョンを保証します。

Apple ID の認証情報ではなく App Store Connect API キーを使う

API キーは 2FA プロンプトを回避でき、CI 環境ではより安全です。

CI では match --readonly を使う

新しい証明書が誤って作成されるのを防ぎます。証明書は必要なときにだけ手動で生成します。

CI 環境では setup_ci を使う

これにより一時的なキーチェーンが作成され、システムキーチェーンを汚さずに済み、キーチェーンの権限ダイアログを防げます。

ビルドを速くするために DerivedData を保持する

専用 Mac では、derived_data_path を指定して、実行間でビルド成果物を再利用します。

関連ガイド

今日から iOS のリリースを自動化しましょう

専用 Mac Mini M4 を手に入れ、無制限のビルドで Fastlane を実行しましょう。月額$85から。

さらに詳しい情報をお探しですか?

ステップバイステップのセットアップ手順、設定リファレンス、トラブルシューティングについては、完全なドキュメントをご覧ください。

ドキュメントを開く →