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
- Fastlane arxitekturasi va fayllar ierarxiyasi
- Appfile va Matchfile: Ko'p muhitli konfiguratsiya
- fastlane match: Sertifikatlarni markazlashtirilgan sinxronlash
- fastlane scan: Barqaror va parallel testlash
- fastlane gym: Deterministik arxivlash va eksport
- fastlane pilot va deliver: TestFlight va App Store avtomatizatsiyasi
- To'liq ishlab chiqarish Fastfile: Multi-flavor lane'lar
- Custom Actions: O'z vositalaringizni yaratish
- Xulosa
- 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}
Fastfileyordamida barcha murakkabxcodebuildbuyruqlari bitta o'qilishi oson buyruqqa aylanadi (bundle exec fastlane beta_staging).matchorqali "Certificates expired" yoki "Provisioning Profile mismatch" muammosi 100% yechiladi.- App Store Connect API Key yordamida SMS va 2FA kodlarisiz xavfsiz CI deploy amalga oshiriladi.