CodePush (App Center mirası ve topluluk devamları), native binary değiştirmeden JavaScript bundle ve asset’leri cihazlara dağıtır. Buna OTA (Over-The-Air — mağaza dışı güncelleme) denir.
Doğru kullanıldığında hotfix günlerden dakikalara iner; yanlış kullanıldığında “yarı güncellenmiş” kullanıcı, okunamaz crash ve store politika riski doğar. OTA bir dağıtım kanalıdır — mimari kaçış kapısı veya native upgrade yerine geçmez.
OTA neyi günceller, neyi güncellemez?
- JS/TS bundle (Hermes
.hbcbytecode dahil) - Packager asset’leri: görseller, fontlar, Lottie JSON (native taraf değişmediyse)
- Remote config driven UI logic — native API sözleşmesi aynı kaldığı sürece
- Yeni native SDK, Gradle/Pod dependency, izin manifest değişikliği
- Turbo Module / Fabric native implementasyon değişikliği
- Hermes veya RN native sürüm değişikliği
- Store politika gerektiren binary değişiklikleri
Altın kural: Native sözleşme kırıldıysa OTA değil, store release.
Mimari akış
- CI, store ile aynı binary target’a karşı bundle üretir (
targetBinaryVersion). - Bundle Hermes bytecode’a derlenir (release Hermes kullanıyorsa).
- Source map üretilir ve OTA label ile arşivlenir.
- Staging’e yayınlanır.
- QA smoke: login, ödeme, offline, deep link.
- Production’a kademeli rollout.
- Crash spike → rollback (önceki bundle label).
Kim staging’e basar, kim production promote eder, kim rollback yetkisine sahip — net olsun.
Staging / production ve binary eşlemesi
En az iki deployment:
- Staging: internal cohort
- Production: gerçek kullanıcılar
targetBinaryVersion şarttır. 1.8.1 binary’sine 1.8.2 native API bekleyen bundle basmak klasik outage’tır.
Pratikler:
- Binary semver ile OTA label’ı karıştırmayın
- iOS ve Android ayrı bundle, ayrı metrik
- Uyumsuz bundle asla publish edilmemeli
Mandatory vs optional
| Politika | Ne zaman | Risk |
|---|---|---|
| Optional | UX iyileştirme, düşük risk bug | Kullanıcı eski bundle’da kalabilir |
| Mandatory | Kritik güvenlik, ödeme/data bug | Kötü ağda açılış bloklanır |
Mandatory’yi ürün silahı yapmayın. Çoğu hotfix optional + restart prompt yeter. Mandatory’de progress UI, timeout/retry ve rollback runbook hazır olsun.
Hermes ve CodePush
Release binary Hermes kullanıyorsa OTA artifact da Hermes pipeline’dan geçmeli. Düz JS + Hermes runtime (veya tersi) uyumsuzluk üretir.
CI disiplini: Store bundle komutu = OTA bundle komutu. Tek script, tek metro/Babel config.
Release bundle üretme örneği:
npx react-native bundle \
--platform ios \
--dev false \
--entry-file index.js \
--bundle-output build/main.jsbundle \
--assets-dest build/assets \
--sourcemap-output build/main.jsbundle.map
Source map’i OTA label ile arşivleyin. Sentry/Crashlytics upload OTA publish’in parçası olsun.
Dev bundle (__DEV__ true) production’a asla basılmamalı.
Rollback
- Crash spike eşiği aşıldı.
- Yetkili kişi önceki stable label’a dön.
- CDN/manifest propagation (5–15 dk) — cohort hâlâ yeni indirebilir.
- Crash metrik düşüşü doğrulanır.
- Post-mortem: staging neden yakalamadı?
Rollback’i quarter’da bir bilinçli drill olarak çalıştırın.
Store politika
Apple ve Google, OTA ile store kurallarını delmeyi kısıtlar. JS bug fix genelde kabul edilir; uygulamanın “farklı bir uygulama” gibi davranması risklidir. Regüle sektörde audit trail tutun.
Sık tuzaklar
- Native upgrade’i OTA ile idare etmek
- Uyumsuz bundle + karışık cohort
- Debug bundle production’a basmak
- Source map arşivlememek
- Rollback prova etmemek
- Staging’siz production publish
Production checklist
-
targetBinaryVersiondoğru - Store script = OTA script (Hermes dahil)
- Staging smoke: login, pay, offline, deep link, push
- Source map arşivlendi ve crash servisine upload
- Rollback komutu dokümante; yetkili net
- Mandatory ürün onayı alındı mı?
- iOS + Android ayrı yayın, ayrı metrik
- Rollback drill son 90 günde yapıldı mı?
Özet
CodePush hız kazandırır — disiplin yoksa hız yalnızca outage’ı öne çeker. Native sınırı koruyun, Hermes sözleşmesini CI’da kilitleyin, staging’siz production’a basmayın. OTA, store release’in yerini almaz; aradaki boşluğu güvenli doldurur.