मुख्य सामग्री पर जाएं

Fastlane + समर्पित Mac सर्वर: संपूर्ण ऑटोमेशन गाइड

एक समर्पित Mac Mini M4 सर्वर पर Fastlane का उपयोग करके अपनी संपूर्ण iOS रिलीज़ प्रक्रिया (बिल्ड, कोड साइनिंग, स्क्रीनशॉट और TestFlight डिप्लॉयमेंट) को स्वचालित करें।

CI/CD 35 मिनट का पठन अक्टूबर 2026 में अपडेट किया गया

एक समर्पित Mac पर Fastlane क्यों?

Fastlane iOS और Android विकास के लिए मानक ऑटोमेशन टूल है। यह कोड साइनिंग से लेकर TestFlight डिप्लॉयमेंट तक सब कुछ संभालता है। एक समर्पित Mac Mini M4 पर Fastlane चलाना आपको देता है:

स्थायी कीचेन

कोड साइनिंग सर्टिफ़िकेट रन के बीच बने रहते हैं। हर बिल्ड पर इंपोर्ट/एक्सपोर्ट करने की आवश्यकता नहीं।

तेज़ इंक्रीमेंटल बिल्ड

DerivedData बना रहता है, इसलिए fastlane build 15+ के बजाय 2-4 मिनट लेता है।

सिम्युलेटर स्क्रीनशॉट

सभी डिवाइस आकारों के लिए वास्तविक सिम्युलेटर के साथ fastlane snapshot चलाएं।

विश्वसनीय डिप्लॉय

एक स्थिर, समर्पित Mac सर्वर का अर्थ है कम अस्थिर डिप्लॉयमेंट और कोड साइनिंग समस्याएँ।

Fastlane इंस्टॉल करें

अपने समर्पित Mac mini M4 बिल्ड सर्वर में SSH करें और Fastlane इंस्टॉल करें। CI के लिए हम Bundler की सलाह देते हैं: Gemfile, Fastlane का वर्ज़न तय कर देता है ताकि हर रन वही वर्ज़न इस्तेमाल करे, जबकि Homebrew लोकल इस्तेमाल के लिए ठीक है। macOS का सिस्टम Ruby इस्तेमाल न करें: Fastlane के मौजूदा वर्ज़न को Ruby 3.1 या उससे नया चाहिए।

विकल्प A: Bundler और Gemfile (CI के लिए अनुशंसित)

# Ruby 3.1 or later (current Fastlane releases need it; the macOS system Ruby is older)
# Homebrew not installed yet? Install it first, see Option B.
brew install ruby
echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zprofile
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"

# In your project, a Gemfile that pins Fastlane
cd /path/to/your/ios-project
cat > Gemfile <<'EOF'
source "https://rubygems.org"

gem "fastlane", "~> 2.240"
gem "cocoapods"  # if using CocoaPods
EOF

bundle install

# Commit Gemfile and Gemfile.lock, then always run Fastlane through Bundler
bundle exec fastlane --version

विकल्प B: 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 आरंभ करें

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

# Initialize Fastlane (with the Homebrew install, run: fastlane init)
bundle exec fastlane init

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

कोड साइनिंग के लिए Match कॉन्फ़िगर करें

Fastlane Match आपके कोड साइनिंग सर्टिफ़िकेट और प्रोविज़निंग प्रोफ़ाइल को एक निजी Git रिपॉज़िटरी या क्लाउड स्टोरेज में संग्रहीत करता है। यह सुनिश्चित करता है कि सभी मशीनें (और टीम सदस्य) समान साइनिंग पहचान का उपयोग करें।

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

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",
      # Outside the checkout, so it survives the next git clean
      derived_data_path: File.expand_path("~/DerivedData/MyApp"),
      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 17"],  # any device from: xcrun simctl list devices available
      derived_data_path: File.expand_path("~/DerivedData/MyApp"),
      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 (the API key avoids an Apple ID login and 2FA)
    increment_build_number(
      build_number: latest_testflight_build_number(
        api_key_path: "fastlane/AuthKey.json"
      ) + 1
    )

    # Build the app
    build_app(
      workspace: "MyApp.xcworkspace",
      scheme: "MyApp",
      export_method: "app-store",
      derived_data_path: File.expand_path("~/DerivedData/MyApp"),
      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(
        api_key_path: "fastlane/AuthKey.json"
      ) + 1
    )

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

    upload_to_app_store(
      submit_for_review: true,
      automatic_release: false,
      api_key_path: "fastlane/AuthKey.json",
      precheck_include_in_app_purchases: false,
      force: true  # skip the HTML preview prompt, which fails in non-interactive CI
    )

    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

स्वचालित स्क्रीनशॉट सेट करें

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

# Simulator names from: xcrun simctl list devices available
devices([
  "iPhone 17 Pro Max",
  "iPhone 17",
  "iPad Pro 13-inch (M5)"
])

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",
      force: true  # skip the HTML preview prompt when run in CI
    )
  end

TestFlight पर डिप्लॉय करें

CI वातावरणों के लिए, अपने Apple ID क्रेडेंशियल के बजाय App Store Connect API कुंजी का उपयोग करें। यह हेडलेस सर्वरों पर 2FA प्रॉम्प्ट से बचाता है।

एक API कुंजी बनाएं

  1. App Store Connect > Users and Access > Integrations > App Store Connect API पर जाएं
  2. एक नई API कुंजी जनरेट करने के लिए + बटन पर क्लिक करें
  3. App Manager भूमिका चुनें
  4. .p8 फ़ाइल डाउनलोड करें
  5. Key ID और Issuer 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

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]
    # push_to_git_remote needs write access: the token is read-only by default
    permissions:
      contents: write

    env:
      # Xcode for this job, without sudo (path from `xcodes installed`)
      DEVELOPER_DIR: /Applications/Xcode-27.0.0.app/Contents/Developer
      MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
      # base64 of "github_username:personal_access_token", for example:
      #   echo -n your_github_username:your_personal_access_token | base64
      MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}

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

      - name: Use the Homebrew Ruby (3.1 or later)
        run: echo "/opt/homebrew/opt/ruby/bin" >> "$GITHUB_PATH"

      - 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

सर्वोत्तम प्रथाएँ

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/माह (USD, कर अतिरिक्त) से शुरू।

My Remote Mac की कीमतें USD में, कर अतिरिक्त।

और जानकारी चाहिए?

चरण-दर-चरण सेटअप, कॉन्फ़िगरेशन संदर्भ और समस्या-निवारण के लिए संपूर्ण दस्तावेज़ देखें।

दस्तावेज़ खोलें →