Saltar al contenido principal

Análisis post mortem de la interrupción en Android de React Native 0.71-RC0

· 8 min de lectura
Nicola Corti
Nicola Corti
Software Engineer @ Meta
Lorenzo Sciandra
Lorenzo Sciandra
Senior Software Engineer @ Microsoft
Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Ahora que 0.71 está disponible, queremos compartir información clave sobre el incidente que interrumpió las compilaciones de Android para todas las versiones de React Native durante el lanzamiento del primer candidato a versión 0.71 para compilaciones de React Native y Expo Android el 4 de noviembre de 2022.

Los colaboradores que ayudaron a resolver el incidente asistieron recientemente a una reunión post mortem para discutir en detalle lo sucedido, lo aprendido y las acciones que tomaremos para evitar interrupciones similares en el futuro.

Qué sucedió

El 4 de noviembre de 2022, publicamos la versión 0.71.0-rc0 de React Native, el primer candidato a versión para 0.71, en varios repositorios públicos.

Un cambio importante en este candidato a versión mejoró los tiempos de compilación al publicar artefactos en Maven Central, en lugar de generarlos desde el código fuente. Más detalles sobre esta implementación están disponibles en RFC#508 y discusiones relacionadas.

Desafortunadamente, debido a cómo estructuramos nuevos proyectos desde la plantilla, esto causó fallas en compilaciones para usuarios de Android en versiones anteriores, ya que comenzaron a descargar artefactos nuevos para 0.71.0-rc0 en lugar de la versión que usaban en su proyecto (como 0.68.0).

Por qué sucedió

La plantilla de React Native proporciona un archivo build.gradle para compilar aplicaciones Android. Este archivo contiene una dependencia de la biblioteca Android de React Native así: implementation("com.facebook.react:react-native:+").

Es importante destacar que la parte + de esta dependencia (una versión dinámica de Gradle) indica a Gradle que seleccione la versión más reciente disponible de React Native. Usar versiones dinámicas de Gradle se considera un antipatrón ya que expone a los usuarios a compilaciones menos reproducibles.

Estábamos conscientes de los problemas que podían causar las versiones dinámicas, por lo que en 0.71 limpiamos la nueva plantilla de aplicación y eliminamos todas las dependencias con +. Sin embargo, usuarios en versiones anteriores de React Native seguían usando una versión con +.

Esto hizo que las compilaciones con versiones de React Native anteriores a 0.71.0-rc.0 consultaran todos los repositorios buscando las versiones más recientes disponibles de React Native. Debido a que la recién publicada versión 0.71.0-rc.0 en Maven Central se convirtió en la versión más reciente disponible, las compilaciones con versiones anteriores a 0.71.0-rc.0 comenzaron a usar artefactos de 0.71.0-rc.0. La discrepancia entre la versión local de React Native (ej. 0.68.0) y los artefactos de Maven Central (0.71.0-rc.0) causó que estas compilaciones fallaran.

Detalles técnicos adicionales sobre este evento también están disponibles en este issue de GitHub.

Cómo mitigamos y resolvimos

Tan pronto identificamos el problema el 4 de noviembre, la comunidad encontró y compartió una solución manual que corregía el error al fijar React Native a una versión específica.

Luego, durante el fin de semana del 5 y 6 de noviembre, el equipo de lanzamientos publicó parches para todas las versiones anteriores de React Native hasta la 0.63, los cuales aplicaban automáticamente la corrección para que los usuarios pudieran actualizar a una versión corregida de React Native.

Al mismo tiempo, contactamos a Sonatype para solicitar la eliminación de los artefactos problemáticos.

El problema se resolvió completamente el 8 de noviembre cuando los artefactos fueron eliminados completamente de Maven Central.

Cronología de eventos

Este apartado contiene una línea temporal resumida de los eventos. Todas las horas están en GMT/UTC +0

Lecciones Aprendidas

Aunque las condiciones que desencadenaron este incidente existían desde React Native 0.12.0, queremos asegurar que los cimientos sobre los que desarrollamos y publicamos React Native sean más sólidos. Estas son algunas lecciones aprendidas y acciones concretas para adaptar nuestros procesos e infraestructura y responder más rápido y mejor en el futuro.

Estrategia de respuesta a incidentes

Este incidente reveló carencias en nuestra estrategia de respuesta a problemas de código abierto en React Native.

La comunidad encontró una solución alternativa en menos de 2 horas. Debido a nuestra falta de visibilidad sobre el alcance del problema y la complejidad para corregir versiones antiguas, dependimos de que los afectados descubrieran la solución en el issue de GitHub.

Tardamos 48 horas en reconocer el alcance completo y que no podíamos depender de que todos encontraran el issue. Necesitábamos priorizar mitigaciones activas más complejas para corregir automáticamente los proyectos.

Revisaremos nuestros procesos para decidir cuándo depender de soluciones manuales versus correcciones automáticas. También exploraremos opciones para obtener un mejor diagnóstico en tiempo real del ecosistema.

Política de soporte de versiones

Como muestra la herramienta rn-versions, para cubrir más del 90% de la base de desarrolladores durante el incidente, tuvimos que publicar parches hasta la versión 0.63.

Creemos que esto fue causado por la experiencia de actualización de React Native, históricamente llena de fricciones. Actualmente estamos explorando formas de mejorar esta experiencia para que sea más fluida y rápida, mitigando así la fragmentación del ecosistema.

El lanzamiento de una nueva versión de React Native nunca debería afectar a usuarios de versiones anteriores, y queremos disculparnos por las interrupciones causadas en sus flujos de trabajo.

Asimismo, queremos recalcar la importancia de mantener actualizadas tus dependencias y React Native para beneficiarte de las mejoras y salvaguardas implementadas. Este incidente ocurrió mientras se definía una política oficial de soporte de versiones que aún no se había comunicado ni implementado.

En el futuro, comunicaremos nuestra política de soporte a través de nuestros canales oficiales y consideraremos depreciar versiones antiguas de React Native en npm.

Mejoras en pruebas y mejores prácticas para bibliotecas de terceros

Este incidente destacó la importancia de contar con mejores pruebas de lanzamiento y mejores directrices para bibliotecas de terceros.

En cuanto a pruebas, publicar versiones hasta 0.63.x resultó complejo debido a la falta de automatización y pruebas que ahora tenemos para versiones estables. Reconocemos la importancia de nuestra infraestructura de lanzamiento y pruebas, e invertiremos más en ella en el futuro.

Específicamente, ahora fomentamos y apoyamos las pruebas de bibliotecas de terceros como parte del proceso de lanzamiento de React Native. También estamos añadiendo nuevos canales y roles en el Servidor de Discord para Contribuidores Principales.

Además, iniciamos una colaboración más estrecha con Callstack, mantenedores de create-react-native-library, para mejorar la plantilla de bibliotecas y asegurar que sigue las mejores prácticas necesarias para integrarse con proyectos React Native. La versión más reciente de create-react-native-library ahora es totalmente compatible con proyectos 0.71 manteniendo retrocompatibilidad.

Conclusiones

Queremos disculparnos por las interrupciones causadas a los flujos de trabajo de desarrolladores en todo el mundo. Como destacamos anteriormente, ya hemos comenzado a tomar medidas para fortalecer nuestros fundamentos, y queda más trabajo por hacer.

Esperamos que compartir estas reflexiones les ayude a comprender mejor este incidente y que puedan aplicar nuestros aprendizajes para implementar mejores prácticas en sus propias herramientas y proyectos.

Finalmente, queremos agradecer nuevamente a Sonatype por ayudarnos a eliminar los artefactos, a nuestra comunidad y al equipo de lanzamiento que trabajó incansablemente para resolver esto lo antes posible.