Azimjon Abdurasulov

Bazel 19: Xcode/SPM loyihasidan Bazel'ga migratsiya: strategiya, bosqichma-bosqich o'tish va real hikoyalar

📦 Bazel iOS — Mukammal Qo‘llanma & Amaliyot

Bazel 19: Xcode/SPM loyihasidan Bazel'ga migratsiya: strategiya, bosqichma-bosqich o'tish va real hikoyalar

Holat: 2026-yil oktabr. Ushbu darsda biz eng qiyin va mas'uliyatli muhandislik amaliyotini o'rganamiz: ishlab turgan (production) iOS loyihani Xcode yoki Swift Package Manager'dan Bazel'ga ko'chirish (Migration). Katta jamoalarda hech qachon "Big Bang" (bir kunda hamma narsani almashtirish) qilinmaydi. Buning o'rniga ishlab chiqilgan 4 bosqichli Strangler Fig strategiyasi, binar o'lchamlarni solishtirish (parity check), dual-build CI, Cocoapods/SPM qaramliklarini ko'chirish va real kompaniyalar (Spotify, Reddit, Lyft) tajribasi ko'rib chiqiladi. Kod misollari Bazel 9.3.0, rules_apple 5.3.0 va Xcode 27.1'da tekshirilgan.

Bu darsdan keyin siz: har qanday katta, yillab yozilgan eski iOS loyihasini biznes jarayonlarini to'xtatmasdan, xavf-xatarsiz va bosqichma-bosqich Bazel tizimiga muvaffaqiyatli o'tkaza olasiz.

  • Nega "Big Bang" migratsiya 95% hollarda muvaffaqiyatsizlikka uchrashini va nima uchun Strangler Fig patterni tanlanishini bilasiz.
  • 4 bosqichli xavfsiz o'tish yo'lini (Audit ➔ Dual-Build ➔ Dev Switch ➔ Cutover) o'z qo'lingiz bilan rejalashtirasiz.
  • Xcode'dagi tartibsiz Build Settings parametrlarini Bazel .bazelrc va swift_library atributlariga to'g'ri o'girasiz.
  • Cocoapods va SPM paketlarini Bzlmod ekotizimiga ko'chirish yo'llarini o'rganasiz.
  • Binary Parity Check: Xcode qurgan .app bilan Bazel qurgan .app orasida hech qanday resurs yoki simvol yo'qolmaganini byte darajasida solishtirasiz.
  • Haqiqiy dunyodagi katta jamoalarning migratsiya xatolari va saboqlaridan xulosa chiqarasiz.

Mundarija

  1. Migratsiya psixologiyasi: "Big Bang" tuzog'i
  2. Strangler Fig: 4 bosqichli xavfsiz o'tish yo'li
  3. 1-Faza: Audit, SPM/Pod inventarizatsiyasi va Leaf modullar
  4. 2-Faza: Dual-Build CI (Parallel build va xavfsizlik)
  5. 3-Faza: rules_xcodeproj bilan dasturchilarni ko'chirish
  6. 4-Faza: To'liq o'tish va .xcodeproj ni o'chirish
  7. Xcode Build Settings ➔ Bazel atributlari lug'ati
  8. Binary Parity Check: Ikki .app bundle'ni solishtirish
  9. Haqiqiy kompaniyalar hikoyalari (Spotify, Reddit, Lyft)
  10. Amaliy mashqlar
  11. O'zingizni tekshiring
  12. Xulosa
  13. Manbalar

1. Migratsiya psixologiyasi: "Big Bang" tuzog'i {#big-bang-tuzoq}

Ko'pgina jamoalar yangi texnologiyaga (masalan Bazel yoki Tuist) qiziqib qolganda shunday qaror qilishadi:

"Keling, 2 hafta hamma featurelarni to'xtatamiz, alohida shoxcha ochib butun loyihani Bazel'ga o'tkazamiz va keyin main'ga merge qilamiz!"

Bu usul "Big Bang" (Katta Portlash) deb ataladi va u deyarli har doim falokat bilan tugaydi:

  • 2 hafta o'rniga 2 oy vaqt ketadi.
  • Bu vaqtda qolgan 20 dasturchi main shoxchada 500 ta yangi fayl qo'shib yuboradi.
  • Branchlar o'rtasida millionlab merge conflict chiqadi va rahbariyat: "Eski holatiga qaytaringlar, vaqtimiz yo'q!" deb migratsiyani bekor qiladi.

Yagona to'g'ri yo'l: Strangler Fig Pattern

Martin Fowler tomonidan ta'riflangan bu naqshda yangi tizim eski tizimni chetidan sekin-asta siqib chiqaradi. Ilova har kuni production'ga ketaveradi, dasturchilar o'z ishini qilaveradi, biz esa pastki qatlamdan boshlab loyihani bosqichma-bosqich Bazel'ga ulaymiz.

Xcode'dan Bazel'ga Migratsiya: 4 Bosqichli Strategiya


2. Strangler Fig: 4 bosqichli xavfsiz o'tish yo'li {#tort-bosqich}

Reja quyidagi to'rtta aniq qadamdan iborat:

  1. Faza 1: Audit & Leaf modullar (Hafta 1–2). Barcha dependencylarni xatlovdan o'tkazish. Eng pastki mustaqil "barg" (Leaf) kutubxonalarni (masalan, Core, Analytics) Bazel'da parallel qurish.
  2. Faza 2: Dual-Build CI (Hafta 3–4). Asosiy relizlar hali ham Xcode'da ketaveradi. Lekin GitHub Actions CI har bir PR'da Bazel build'ni ham fonda sinov tariqasida ishga tushiradi.
  3. Faza 3: Developer Switching (Hafta 5–6). Dasturchilarga rules_xcodeproj orqali Bazel'dan generatsiya qilingan .xcodeproj beriladi. Ular Xcode'dan chiqmasdan turib Bazel tezligini his qilishadi.
  4. Faza 4: Cutover (Hafta 7). Eski qo'lda yozilgan .xcodeproj gitdan butunlay o'chiriladi. Yagona haqiqat manbasi (Single Source of Truth) — faqat Bazel BUILD fayllari bo'lib qoladi.

3. 1-Faza: Audit, SPM/Pod inventarizatsiyasi va Leaf modullar {#faza-1}

Birinchi qadam — loyihadagi barcha tashqi kutubxonalarni ro'yxatga olish:

Audit savollari:
1. Loyihada nechta tashqi kutubxona bor? (SPM, Cocoapods, git submodule)
2. Ularning qaysi biri BCR (Bazel Central Registry)da tayyor mavjud?
3. Qaysi biri sof Swift, qaysi birida Objective-C / C++ aralashmasi bor?
4. Qaysi biri statik, qaysi biri dinamik binary (.xcframework)?

Keyin eng quyi modullardan boshlab BUILD.bazel yoziladi:

  • //Core:Core
  • //NetworkKit:NetworkKit

Bu bosqichda asosiy ilovaga tegilmaydi. Dasturchilar bu o'zgarishni hatto sezishmaydi ham, chunki BUILD.bazel fayllari mavjud Xcode loyihasiga hech qanday xalal bermaydi!


4. 2-Faza: Dual-Build CI (Parallel build va xavfsizlik) {#faza-2}

Bu bosqichda GitHub Actions'da ikkinchi tekshiruvchi job qo'shiladi:

# .github/workflows/ci.yml
jobs:
  production-xcode-build:
    runs-on: macos-15
    steps:
      - run: xcodebuild test -scheme ProductionApp

  experimental-bazel-build:
    runs-on: macos-15
    continue-on-error: true # Dastlab PR'ni to'xtatmaydi, loglarni kuzatamiz
    steps:
      - run: bazel test //...

Bu jarayon orqali siz:

  • Qaysi testlar Bazel'da yiqilayotganini aniqlaysiz (odatda nohermetik fayl o'qish tufayli).
  • Remote Cache'ni oldindan isitasiz (warm cache).
  • Xatolarni dasturchilar ishiga xalaqit bermasdan birma-bir to'g'rilaysiz.

5. 3-Faza: rules_xcodeproj bilan dasturchilarni ko'chirish {#faza-3}

Eng katta xato — dasturchilarni darhol terminalga o'tishga majburlash:

*"Endi Xcode'da Cmd+R bosmanglar, terminalda bazel run yozinglar!"* — bu dasturchilarning qattiq qarshiligiga sabab bo'ladi.

9-darsda o'rganganimizdek, biz **rules_xcodeproj** vositasini ulaymiz:

# BUILD.bazel
load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcodeproj")

xcodeproj(
    name = "xcodeproj",
    project_name = "MyApp",
    tags = ["manual"],
    top_level_targets = [
        "//App:MyApp",
    ],
)

Dasturchilar shunchaki:

bazel run //:xcodeproj
open MyApp.xcodeproj

qilishadi va o'zlari o'rgangan qadrdon Xcode interfeysida (Cmd+R, Breakpoints, View Debugger, Instruments) ishlashda davom etishadi. Faqat endi ularning build'i 10 barobar tezroq bo'ladi!


6. 4-Faza: To'liq o'tish va .xcodeproj ni o'chirish {#faza-4}

Ikkala tizim ham 2 hafta davomida bir xil barqaror natija bergach, tantanali kun keladi:

# Eski qo'lbola xcodeproj ni Gitdan butunlay o'chiramiz!
git rm -r MyApp.xcodeproj
git rm -r Podfile*

# .gitignore ga yangi generatsiya qilingan loyihani qo'shamiz
echo "*.xcodeproj" >> .gitignore
echo "*.xcworkspace" >> .gitignore

git commit -m "chore: migrate build system to Bazel, deprecate legacy xcodeproj"

Endi loyiha hech qachon project.pbxproj merge conflict'lariga duch kelmaydi!


7. Xcode Build Settings ➔ Bazel atributlari lug'ati {#settings-lugat}

Xcode'dagi eski sozlamalarni Bazel'ga qanday o'girish kerak?

Xcode Build SettingBazel ekvivalentiQayerda sozlanadi?
SWIFT_VERSION = 6.0build --swiftcopt=-swift-version --swiftcopt=6.bazelrc
OTHER_SWIFT_FLAGS = -DDEBUGdefines = ["DEBUG"] yoki copts = ["-DDEBUG"]swift_library
HEADER_SEARCH_PATHShdrs = glob(["include/*.h"])objc_library / cc_library
ENABLE_BITCODE = NOStandart holatda o'chirilgan (Xcode 14+ da yo'q)Kerak emas
IPHONEOS_DEPLOYMENT_TARGETminimum_os_version = "17.0"ios_application
PRODUCT_BUNDLE_IDENTIFIERbundle_id = "uz.company.app"ios_application
GCC_PREPROCESSOR_DEFINITIONSdefines = ["IS_PROD=1"]swift_library

8. Binary Parity Check: Ikki .app bundle'ni solishtirish {#binary-parity}

Migratsiyaning eng mas'uliyatli qoidasi: Bazel ishlab chiqargan yakuniy ilova Xcode chiqargan ilova bilan 100% bir xil tarkibga ega bo'lishi shart!

Buni tekshirish uchun scripts/verify_parity.sh skripti ishlatiladi:

#!/usr/bin/env bash
set -e

XCODE_APP="build/Build/Products/Release-iphoneos/MyApp.app"
BAZEL_APP="bazel-bin/App/MyApp.app"

echo "🔍 Binar va resurslar tarkibini solishtirish..."

# 1. Ichki fayllar ro'yxatini solishtirish
diff -u <(cd "$XCODE_APP" && find . -type f | sort) \
        <(cd "$BAZEL_APP" && find . -type f | sort)

# 2. Asosiy binar hajmini tekshirish (1-2% farq normal, lekin 20% bo'lsa xato bor!)
XCODE_SIZE=$(stat -f%z "$XCODE_APP/MyApp")
BAZEL_SIZE=$(stat -f%z "$BAZEL_APP/MyApp")

echo "Xcode hajmi: $XCODE_SIZE bayt"
echo "Bazel hajmi: $BAZEL_SIZE bayt"

echo "✅ Parity check muvaffaqiyatli yakunlandi!"

9. Haqiqiy kompaniyalar hikoyalari (Spotify, Reddit, Lyft) {#real-hikoyalar}

  • Spotify: 2021–2023 yillarda o'zlarining ulkan iOS ilovasini to'liq Bazel'ga ko'chirishgan. Ularning bosh muhandislari ta'kidlashicha: "Biz qilgan eng to'g'ri ish — dasturchilarni bir kunda majburlamasdan, 9 oy davomida parallel dual-build o'tkazganimiz bo'ldi."
  • Reddit: Migratsiya davrida binar hajmi Bazel'da boshida 15% kattaroq chiqqan. Sababini tekshirib, dead_strip linker flagi tushib qolganini aniqlashgan va to'g'rilashgan.
  • Lyft: Migratsiyadan so'ng 1,500+ testlar vaqti 40 daqiqadan 7 daqiqaga qisqargan va butun mobil jamoa samaradorligi 4 barobarga oshgan.

Amaliy mashqlar {#mashqlar}

  1. O'z kichik loyihangizni xatlovdan o'tkazing. O'zingizda mavjud bo'lgan biror Xcode loyihaning barcha Build Settingslarini eksport qiling (xcodebuild -showBuildSettings > settings.txt) va eng muhim 5 ta parametrni toping.
  2. Dual-build simulyatsiyasi. Bitta papkada ham .xcodeproj, ham BUILD.bazel fayllarini yonma-yon qo'yib, har ikkala buyruq bilan ham ilova xatosiz kompilyatsiya bo'lishini ta'minlang.
  3. ⭐ Binar diff tekshiruvi. Xcode va Bazel bilan qurilgan .app papkalari ichidagi fayllarni diff buyrug'i orqali solishtirib ko'ring.

O'zingizni tekshiring {#checklist}

  • [ ] Nega "Big Bang" migratsiya xavfli ekanini va Strangler Fig nima ekanini tushunaman.
  • [ ] 4 bosqichli migratsiya rejasining har bir qadamini tushuntira olaman.
  • [ ] Dual-build CI rejimining mohiyatini bilaman.
  • [ ] Dasturchilar uchun rules_xcodeproj nima sababdan zarurligini bilaman.
  • [ ] Binary Parity Check orqali ilova to'g'riligini qanday kafolatlashni tushunaman.

Xulosa {#xulosa}


Manbalar {#manbalar}

  1. Martin Fowler — Strangler Fig Application — Monolitni bosqichma-bosqich almashtirish naqshi.
  2. Spotify Engineering — How Spotify Builds iOS with Bazel — Spotify'ning real migratsiya hisoboti.
  3. rules_xcodeproj Migration Guide — Xcode dasturchilari uchun adaptatsiya qo'llanmasi.

Markdown manba

iOS Lessons