Azimjon Abdurasulov

DevOps 2: Fastlane Chuqur Amaliyot — Match, Gym, Pilot va Multi-Flavor Pipeline

🛠️ DevOps Engineering

DevOps 2: Fastlane Chuqur Amaliyot — Match, Gym, Pilot va Multi-Flavor Pipeline

Holat: 2026-yil sentabr. Fastlane — iOS va Android ilovalarini avtomatlashtirilgan tarzda yig'ish, imzolash va App Store Connect'ga yuklash bo'yicha sanoat standarti hisoblanadi. Ushbu darsda ko'p muhitli (multi-flavor/multi-target) haqiqiy production darajasidagi Fastlane pipeline'ini noldan qanday loyihalash tushuntiriladi.

Mundarija

  1. Fastlane arxitekturasi va fayllar ierarxiyasi
  2. Appfile va Matchfile: Ko'p muhitli konfiguratsiya
  3. fastlane match: Sertifikatlarni markazlashtirilgan sinxronlash
  4. fastlane scan: Barqaror va parallel testlash
  5. fastlane gym: Deterministik arxivlash va eksport
  6. fastlane pilot va deliver: TestFlight va App Store avtomatizatsiyasi
  7. To'liq ishlab chiqarish Fastfile: Multi-flavor lane'lar
  8. Custom Actions: O'z vositalaringizni yaratish
  9. Xulosa
  10. Manbalar

1. Fastlane arxitekturasi va fayllar ierarxiyasi {#arxitektura}

Professional loyihada fastlane/ katalogi quyidagi tartibda saqlanadi:

my-ios-app/
├── Gemfile               # fastlane va plaginlar versiyasi qat'iy qulflanadi
├── Gemfile.lock
├── fastlane/
│   ├── Appfile           # Apple ID, Team ID, Bundle ID ta'riflari
│   ├── Matchfile         # Sertifikatlar ombori sozlamalari
│   ├── Fastfile          # Asosiy pipeline lane'lari
│   ├── actions/          # Maxsus ruby action'lari
│   └── metadata/         # App Store tavsiflari va skrinshotlari

Gemfile deterministik bo'lishi shart:

# frozen_string_literal: true

source "https://rubygems.org"

gem "fastlane", ">= 2.225.0"
gem "cocoapods", require: false

2. Appfile va Matchfile: Ko'p muhitli konfiguratsiya {#appfile-matchfile}

Bitta ilovaning Dev, Staging va Production muhitlari turli xil Bundle Identifier'larga ega bo'ladi (uz.azimjondev.app.dev, uz.azimjondev.app.staging, uz.azimjondev.app):

fastlane/Appfile

# Appfile — muhitlar bo'yicha dinamik konfiguratsiya
apple_id(ENV["APPLE_ID"] || "dev@azimjondev.uz")
team_id("ABCDE12345")
itc_team_id("987654321")

for_lane :beta_staging do
  app_identifier("uz.azimjondev.app.staging")
end

for_lane :release_prod do
  app_identifier("uz.azimjondev.app")
end

fastlane/Matchfile

# Matchfile — Git yoki S3 orqali sertifikatlarni saqlash
git_url("git@github.com:my-company/ios-certificates.git")
storage_mode("git")
type("appstore") # development, adhoc, appstore, enterprise

# CI serverda yangi sertifikat yaratishni taqiqlash (faqat o'qish):
readonly(ENV["CI"] == "true")

3. fastlane match: Sertifikatlarni markazlashtirilgan sinxronlash {#match}

match vositasining asosiy g'oyasi — "Code Signing kimningdir kompyuterida tasodifan yaratilmasin". Barcha sertifikatlar va provisioning profile'lar Git omborida (yoki AWS S3 / Google Cloud Storage'da) OpenSSL AES-256 bilan shifrlangan holda saqlanadi:

# Yangi dasturchi qo'shilganda parolni kiritadi va profilni oladi:
bundle exec fastlane match appstore --readonly

# Yangi sertifikat va profile generatsiya qilish (faqat Lead):
bundle exec fastlane match appstore -a uz.azimjondev.app

CI serverda parol MATCH_PASSWORD environment variable orqali uzatiladi.


4. fastlane scan: Barqaror va parallel testlash {#scan}

Testlar flakiness (beqarorlik) tufayli yiqilmasligi uchun scan sozlamalari:

lane :test do
  scan(
    workspace: "AzimjonDev.xcworkspace",
    scheme: "AzimjonDev",
    devices: ["iPhone 16 Pro"],
    clean: false,
    number_of_retries: 2, # Yiqilgan testni 2 martagacha qayta tekshirish
    fail_build: true,
    output_types: "html,junit",
    output_directory: "./build/reports",
    xcargs: "-parallel-testing-enabled YES -maximum-concurrent-test-simulator-destinations 4"
  )
end

5. fastlane gym: Deterministik arxivlash va eksport {#gym}

gym (xcodebuild archive va xcodebuild -exportArchive) ustiga qurilgan qulay wrapper bo'lib, uning yordamida to'g'ri imzolangan .ipa hosil qilinadi:

lane :build_ipa do |options|
  environment = options[:env] || "staging"
  scheme = environment == "prod" ? "AzimjonDev-Prod" : "AzimjonDev-Staging"

  gym(
    workspace: "AzimjonDev.xcworkspace",
    scheme: scheme,
    clean: true,
    output_directory: "./build/artifacts",
    output_name: "AzimjonDev-#{environment}.ipa",
    export_method: "app-store",
    export_options: {
      compileBitcode: false,
      stripSwiftSymbols: true,
      manageAppVersionAndBuildNumber: false
    }
  )
end

6. fastlane pilot va deliver: TestFlight va App Store avtomatizatsiyasi {#pilot-deliver}

TestFlight'ga yuklash (pilot)

lane :upload_testflight do |options|
  api_key = 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
  )

  pilot(
    api_key: api_key,
    ipa: "./build/artifacts/AzimjonDev-staging.ipa",
    skip_waiting_for_build_processing: true, # CI oqimini 20 daqiqa ushlab turmaslik
    changelog: "Staging build ##{ENV['BUILD_NUMBER']}: yangi o'zgarishlar va bug fixlar."
  )
end

7. To'liq ishlab chiqarish Fastfile: Multi-flavor lane'lar {#fastfile}

Quyida real loyihalarda ishlatiladigan to'liq Fastfile namunasi keltirilgan:

default_platform(:ios)

platform :ios do
  before_all do
    ensure_git_status_clean unless ENV["CI"]
  end

  desc "PR uchun testlarni ishga tushirish"
  lane :ci_pr do
    scan(
      scheme: "AzimjonDev-Staging",
      devices: ["iPhone 16 Pro"],
      fail_build: true
    )
  end

  desc "Staging versiyani yig'ish va TestFlight'ga jo'natish"
  lane :beta_staging do
    api_key = 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
    )

    match(type: "appstore", app_identifier: "uz.azimjondev.app.staging", readonly: true)

    gym(
      scheme: "AzimjonDev-Staging",
      output_name: "AzimjonDev-Staging.ipa"
    )

    pilot(
      api_key: api_key,
      ipa: "./build/artifacts/AzimjonDev-Staging.ipa",
      skip_waiting_for_build_processing: true
    )
  end

  desc "Production versiyani App Store Connect'ga yuklash"
  lane :release_prod do
    api_key = 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
    )

    match(type: "appstore", app_identifier: "uz.azimjondev.app", readonly: true)

    gym(
      scheme: "AzimjonDev-Prod",
      output_name: "AzimjonDev-Prod.ipa"
    )

    deliver(
      api_key: api_key,
      ipa: "./build/artifacts/AzimjonDev-Prod.ipa",
      skip_screenshots: true,
      skip_metadata: true,
      submit_for_review: false
    )
  end

  after_all do |lane|
    UI.success("Lane #{lane} muvaffaqiyatli yakunlandi! 🚀")
  end

  error do |lane, exception|
    UI.error("Lane #{lane}da xatolik: #{exception.message}")
  end
end

8. Custom Actions: O'z vositalaringizni yaratish {#custom-actions}

Agar mavjud Fastlane action'lari yetarli bo'lmasa (masalan, ichki Telegram chatga xabar yuborish), fastlane/actions/notify_telegram.rb yaratiladi:

module Fastlane
  module Actions
    class NotifyTelegramAction < Action
      def self.run(params)
        message = params[:message]
        UI.message("Telegram xabari: #{message}")
        # Faraday yoki HTTP orqali bot API'ga so'rov yuborish mumkin
      end

      def self.description
        "Telegram guruhiga build holatini xabar qiladi"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(key: :message, description: "Xabar matni")
        ]
      end

      def self.is_supported?(platform)
        platform == :ios
      end
    end
  end
end

9. Xulosa {#xulosa}

  • Fastfile yordamida barcha murakkab xcodebuild buyruqlari bitta o'qilishi oson buyruqqa aylanadi (bundle exec fastlane beta_staging).
  • match orqali "Certificates expired" yoki "Provisioning Profile mismatch" muammosi 100% yechiladi.
  • App Store Connect API Key yordamida SMS va 2FA kodlarisiz xavfsiz CI deploy amalga oshiriladi.

10. Manbalar {#manbalar}

  1. Fastlane Docs — Code Signing with match
  2. Fastlane Docs — Building with gym
  3. App Store Connect API Key integration in Fastlane

Markdown manba

iOS Lessons