Przejdź do treści głównej

Postmortem awarii w Androidzie dla React Native 0.71-RC0

· 7 minut czytania
Nicola Corti
Nicola Corti
Software Engineer @ Meta
Lorenzo Sciandra
Lorenzo Sciandra
Senior Software Engineer @ Microsoft
Nieoficjalne Tłumaczenie Beta

Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →

Skoro wersja 0.71 jest już dostępna, chcemy podzielić się kluczowymi informacjami o awarii, która przerwała kompilację Androida dla wszystkich wersji React Native podczas wydawania pierwszego kandydata wydania (RC) wersji 0.71 dla React Native i Expo 4 listopada 2022 roku.

Współtwórcy, którzy pomogli w rozwiązaniu problemu, niedawno uczestniczyli w spotkaniu postmortem, aby szczegółowo omówić przebieg zdarzeń, wnioski oraz działania zapobiegające podobnym awariom w przyszłości.

Co się wydarzyło

4 listopada 2022 roku opublikowaliśmy wersję 0.71.0-rc0 React Native, pierwszego kandydata wydania dla wersji 0.71, w kilku publicznych repozytoriach.

Główna zmiana w tym wydaniu kandydackim miała przyspieszyć kompilację poprzez publikowanie artefaktów w Maven Central zamiast budowania ich ze źródeł. Szczegóły tej implementacji dostępne są w RFC#508 i powiązanych dyskusjach.

Niestety, ze względu na sposób tworzenia nowych projektów z szablonu, zmiana ta spowodowała błędy kompilacji dla użytkowników Androida na starszych wersjach, ponieważ system zaczynał pobierać artefakty dla 0.71.0-rc0 zamiast wersji używanej w ich projekcie (np. 0.68.0).

Przyczyna awarii

Szablon React Native zawiera plik build.gradle do budowania aplikacji Android. Plik ten zawiera zależność od biblioteki React Native dla Androida w formacie: implementation("com.facebook.react:react-native:+").

Znak + w tej zależności (tzw. dynamiczna wersja Gradle) nakazuje Gradle wybór najnowszej dostępnej wersji React Native. Używanie dynamicznych wersji jest antywzorcem, ponieważ naraża użytkowników na mniej powtarzalne kompilacje.

Zdawaliśmy sobie sprawę z problemów związanych z dynamicznymi wersjami, dlatego w 0.71 wyczyściliśmy szablon nowej aplikacji, usuwając wszystkie zależności zawierające +. Jednak użytkownicy starszych wersji React Native nadal używali wersji z +.

Spowodowało to, że kompilacje z wersjami React Native starszymi niż 0.71.0-rc.0 wyszukiwały we wszystkich repozytoriach najnowszą dostępną wersję React Native. Ponieważ nowo opublikowana wersja 0.71.0-rc.0 w Maven Central stała się najnowszą, kompilacje ze starszymi wersjami zaczęły używać artefaktów z 0.71.0-rc.0. Niedopasowanie wersji między lokalną kompilacją (np. 0.68.0) a artefaktami z Maven Central (0.71.0-rc.0) powodowało błędy tych kompilacji.

Dodatkowe szczegóły techniczne dotyczące tego zdarzenia dostępne są w tym zgłoszeniu na GitHubie.

Działania naprawcze

Natychmiast po zidentyfikowaniu problemu 4 listopada społeczność opracowała i udostępniła ręczne obejście polegające na przypięciu React Native do konkretnej wersji, co korygowało błąd.

Następnie w weekend 5-6 listopada zespół wydań opublikował poprawki dla wszystkich poprzednich wersji React Native aż do wersji 0.63, które automatycznie aplikowały poprawkę, umożliwiając użytkownikom aktualizację do naprawionej wersji.

Jednocześnie zwróciliśmy się do Sonatype z prośbą o usunięcie problematycznych artefaktów.

Problem został całkowicie rozwiązany 8 listopada, gdy artefakty zostały w pełni usunięte z Maven Central.

Oś czasu zdarzeń

Ta sekcja zawiera skrócony przebieg wydarzeń. Wszystkie godziny podane są w GMT/UTC +0

Wyciągnięte wnioski

Chociaż warunki do wystąpienia tego incydentu istniały praktycznie od wersji React Native 0.12.0, chcemy zapewnić solidniejsze podstawy pod przyszły rozwój i wydania frameworka. Poniżej przedstawiamy wyciągnięte wnioski oraz działania, które podejmiemy, aby usprawnić nasze procesy i infrastrukturę.

Strategia reagowania na incydenty

Incydent ujawnił luki w naszym podejściu do reagowania na problemy open-source związane z React Native.

Społeczność szybko znalazła obejście w ciągu 2 godzin. Z powodu ograniczonej widoczności skali problemu oraz złożoności naprawy dla starszych wersji, polegaliśmy na tym, że poszkodowani znajdą obejście w zgłoszeniu na GitHubie.

Dopiero po 48 godzinach zrozumieliśmy pełny zakres problemu i fakt, że nie możemy polegać wyłącznie na GitHubie. Musieliśmy skupić się na bardziej złożonych rozwiązaniach automatycznie naprawiających projekty.

Przejrzymy nasze procesy dotyczące sytuacji, w których lepiej polegać na ręcznych obejściach, a kiedy wdrażać automatyczne poprawki. Zbadamy również możliwości lepszego monitorowania kondycji ekosystemu.

Polityka wsparcia wydań

Jak widać w narzędziu rn-versions, aby objąć ponad 90% bazy deweloperów React Native w czasie incydentu, musieliśmy wydać łatki aż do wersji 0.63.

Uważamy, że przyczyną tego są problemy związane z aktualizacją React Native, które od dawna stanowią wyzwanie. Obecnie pracujemy nad usprawnieniem procesu aktualizacji, aby był on płynniejszy i szybszy, co pomoże zmniejszyć fragmentację ekosystemu.

Wydanie nowszej wersji React Native nigdy nie powinno wpływać na użytkowników korzystających ze starszych wersji. Chcielibyśmy przeprosić za zakłócenia, które spowodowaliśmy w Waszym workflow.

Jednocześnie chcemy podkreślić znaczenie aktualizowania zależności i samego React Native do najnowszych wersji, aby korzystać z wprowadzonych ulepszeń i zabezpieczeń. To zdarzenie miało miejsce w czasie, gdy oficjalna polityka wsparcia wersji była w trakcie definiowania i nie była jeszcze ogłoszona ani egzekwowana.

W przyszłości będziemy informować o naszej polityce wsparcia za pośrednictwem kanałów komunikacyjnych oraz rozważymy oznaczanie starszych wersji React Native jako przestarzałe w npm.

Ulepszone testowanie i najlepsze praktyki dla bibliotek stron trzecich

To zdarzenie podkreśliło znaczenie lepszego testowania wydań oraz lepszych wytycznych dla bibliotek stron trzecich.

Jeśli chodzi o testowanie, wydawanie poprawek aż do wersji 0.63.x okazało się wyzwaniem z powodu braku automatyzacji i testów, które obecnie mamy wdrożone dla stabilnych wydań. Zdajemy sobie sprawę z ważności naszej infrastruktury wydawniczej i testowej i zamierzamy w nią dalej inwestować.

W szczególności zachęcamy i wspieramy testowanie bibliotek stron trzecich jako część procesu wydawania React Native. Dodajemy także nowe kanały i role w serwerze Discord dla głównych współtwórców.

Dodatkowo rozpoczęliśmy ściślejszą współpracę z Callstack, opiekunami narzędzia create-react-native-library, w celu ulepszenia szablonu biblioteki i zapewnienia, że będzie on przestrzegał wszystkich niezbędnych najlepszych praktyk integracji z projektami React Native. Nowsza wersja create-react-native-library jest teraz w pełni kompatybilna z projektami w wersji 0.71, zachowując jednocześnie wsteczną kompatybilność.

Wnioski

Chcemy przeprosić za zakłócenia, które to spowodowało w workflow programistów na całym świecie. Jak podkreślono powyżej, już podjęliśmy działania, aby wzmocnić nasze fundamenty — i przed nami jeszcze więcej pracy.

Mamy nadzieję, że podzielenie się tymi spostrzeżeniami pomoże Wam lepiej zrozumieć to zdarzenie oraz że wykorzystacie nasze doświadczenia, aby stosować lepsze praktyki w swoich narzędziach i projektach.

Na zakończenie jeszcze raz chcemy podziękować firmie Sonatype za pomoc w usunięciu artefaktów, naszej społeczności oraz zespołowi wydawniczemu, który niestrudzenie pracował, aby jak najszybciej rozwiązać ten problem.