Diez ejemplos para coordinar lanzamientos de tiendas nativas con trenes OTA de JavaScript - la base operacional que los equipos móviles empresariales necesitan antes de escalar más allá de un ingeniero etiquetando compilaciones del viernes.
Cada decisión de lanzamiento empresarial comienza con qué reloj le pertenece el cambio:
Clock A - Binario de tienda (eas build + eas submit) Cambios: módulos nativos, bumps de SDK, permisos, derechos, iconos Cadencia: tren de lanzamiento quincenal o mensual Reversión: nueva versión de tienda (horas a días)Clock B - Bundle OTA (eas update) Cambios: JS, TypeScript, activos, copia - mismo runtimeVersion que Clock A Cadencia: diaria a semanal entre trenes de tienda Reversión: eas update:rollback (minutos)
Reloj
Punto de entrada CI
Propietario
Impacto del usuario si está fuera de tiempo
A
eas build en etiqueta
Plataforma móvil
Bloqueo en el lanzamiento, rechazo de tienda
B
eas update en merge
Característica móvil
Interfaz de usuario incorrecta, errores de JS en binario antiguo
Clock A es lento pero cambia el shell nativo - Hermes, módulos nativos, derechos de push
Clock B es rápido pero no puede añadir código nativo - solo JS que el binario ya soporta
Usa una tabla de decisión simple en cada plantilla de PR:
Cambio
Reloj
Por qué
Corrección de color de botón
B (OTA)
JavaScript puro
Nueva dependencia expo-camera
A (tienda)
Módulo nativo - cadenas de permisos
El cliente API lee nuevo campo opcional
B (OTA)
Lector tolerante en JS
Bump de Hermes / SDK 57
A (tienda)
Cambio de runtime nativo
Intercambiar activo de imagen hero
B (OTA)
Activo empaquetado
Agregar NSCameraUsageDescription
A (tienda)
Info.plist en binario
# Fragmento de lista de verificación de PR - pegar en .github/pull_request_template.md## Ruta de entrega- [ ] JS-only → preview soak → production OTA- [ ] Native change → eas build required; OTA blocked until new binary ships
Cada binario de producción debe escuchar en el mismo canal en el que publiques:
# Compilar binario de producción - canal integrado en tiempo de compilacióneas build --profile production --platform all --non-interactive# OTA debe dirigirse al mismo canaleas update --channel production --environment production \ --message "fix: checkout total rounding"
# Verifica la alineación antes de cada OTA de produccióneas channel:view production# Confirma que el canal apunta a la rama de producción y runtimeVersion coincide con app.config
Los canales desalineados causan tickets de soporte "la actualización nunca llega" - no bloqueos
Las aplicaciones con marca blanca necesitan canales separados por bundle ID - nunca compartas un canal de producción
Los equipos empresariales ejecutan un calendario compartido - no hojas de cálculo separadas de iOS, Android y JS:
# Lanzamiento 2.5.0 - Semana del 2026-07-14## Clock A (tienda)- Jue S1: congelación de código 18:00 UTC- Vie S1: etiqueta v2.5.0; eas build de producción; envío controlado- Lun S2: Play escalonado 10% - 50%- Mié S2: Lanzamiento escalonado de ASC 100%## Clock B (OTA)- Lun-Mié S1: OTA solo a canal de vista previa (detrás de flags)- Jue S1: congelar OTA a producción hasta que se firme RC de tienda- Mié S2: carril de hotfix OTA abierto si runtimeVersion no cambia## Dependencias- [ ] API v3 en prod - @backend - Jue S1- [ ] Flag de característica checkout_v3 al 0% - @mobile - Vie S1
Congelación de OTA durante RC de tienda previene la desviación de JS entre la aprobación de QA y el envío
Carril de hotfix se reabre después de que el binario de tienda esté en vivo y runtimeVersion sea estable
El artefacto que QA probó debe ser el artefacto que reciben las tiendas:
# El pipeline de lanzamiento registra build_id en ticketeas build --profile production --platform ios --non-interactive# build_id: abc123-def456-...# QA aprueba abc123 - nunca reconstruya antes de enviareas submit --platform ios --id abc123-def456-... --non-interactive
# .github/workflows/release.yml - enviar ID fijo desde salida de workflow- name: Submit iOS (pinned build) run: eas submit --platform ios --id ${{ needs.build.outputs.ios_build_id }} --non-interactive
Reconstruir entre QA y envío invalida la asignación de simbolización de bloqueos y las capturas de pantalla de revisión
El envío --latest es solo para emergencias - documenta cuándo está permitido
JS que llama a una nueva API no debe enviarse OTA hasta que el backend esté en vivo:
Orden incorrecta: OTA se envía el lunes - API se despliega el jueves - 3 días de 404Orden correcta: API se despliega el jueves (compatible hacia atrás) - OTA se envía el viernes
// src/api/checkout.ts - lector tolerante hasta que el flag se ramifiqueexport async function fetchCheckoutConfig(): Promise<CheckoutConfig> { const res = await api.get("/v3/checkout/config"); if (res.status === 404) { return api.get("/v2/checkout/config"); // alternativa para ruta antigua } return res.json();}
API compatible hacia atrás se despliega primero; mobile OTA habilita la interfaz de usuario a través de flag de característica segundo
Eliminación de API de ruptura requiere binario de tienda Clock A sin llamadas antiguas - coordina ventana de depreciación
Los binarios de tienda pueden estar en revisión durante días mientras JS se envía diariamente - los flags desacoplan en vivo de visible:
Día 1: eas build envía v2.5.0 a TestFlight - flag checkout_v3 APAGADODía 3: eas update envía interfaz de usuario de checkout - todavía oculta detrás de flagDía 5: App Review aprueba; comienza el lanzamiento escalonado - flag 0%Día 7: OTA - flag se incrementan al 10% de cohorte internaDía 10: flag 100% después de que las métricas pasen
Binario en vivo significa que el shell nativo está en la tienda - los usuarios pueden instalarlo
Característica visible significa que el flag (o canal) expone la nueva experiencia
Cuando el tren es solo JS, omite Clock A pero mantén disciplina:
# Lun - merge detrás de flags; publica vista previaeas update --channel preview --environment preview --message "feat: loyalty points UI"# Mar - QA soak en binario de vista previa (mismo runtimeVersion que producción)# Mié - lanzamiento escalonado de produccióneas update --channel production --environment production \ --rollout-percentage=10 --message "rollout: loyalty @ 10%"# Jue - monitorea Sentry; revierte si crash-free cae# Vie - 100% si las métricas se mantienen
Las semanas solo OTA aún necesitan preview soak en rutas de ingresos - los lanzamientos no son un sustituto
Documenta la reversión antes de necesitarla - los incidentes empresariales se mueven más rápido con tarjetas pre-escritas:
Reloj
Disparador
Acción
ETA
B (OTA)
Crash-free -2% después de publicar
eas update:rollback - flag apagado
< 15 min
B (OTA)
Éxito de pago -1%
Flag apagado primero; reversión segundo
< 10 min
A (tienda)
Bloqueo nativo en el lanzamiento
Detener lanzamiento escalonado; promover versión anterior
1-24 hr
A (tienda)
Rechazo de tienda
Corregir binario; reenviar - OTA no puede reparar nativo
días
# Tarjeta de reversión OTA - rellenar por lanzamientoeas update:list --branch production --limit 3# Último conocido como bueno: <update-group-id>eas update:rollback
OTA no puede reparar bloqueos nativos - escalar a binario de hotfix Clock A
Discrepancia de runtimeVersion requiere nueva compilación de tienda - no republicar canal
¿Podemos enviar OTA durante la revisión de App Store?
Sí, si runtimeVersion coincide con el binario en revisión y la OTA no cambia el comportamiento que los revisores probarán. Mantén OTAs de producción detrás de flags hasta la aprobación - los revisores pueden probar una compilación que recibe una OTA en el lanzamiento.
¿Con qué frecuencia los equipos empresariales deben ejecutar trenes de tienda?
Quincenal es común para aplicaciones de consumo; mensual para industrias reguladas. OTA llena el vacío entre trenes - diario o semanal para correcciones de JS. Adapta la cadencia al riesgo de revisión de tienda y ventanas de dependencia de backend.
¿Quién es propietario del calendario de lanzamiento?
Gerente de ingeniería o capitán de lanzamiento - responsable. Se consulta a mobile, backend, QA y soporte. El calendario vive en un documento compartido o epopeya de Jira, no en el cuaderno de un ingeniero.
¿iOS y Android necesitan publicaciones OTA separadas?
Un eas update sirve a ambas plataformas cuando comparten runtimeVersion y canal. Los envíos de tienda siguen siendo por plataforma - EAS Submit.