Postmortem awarii w Androidzie dla React Native 0.71-RC0
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
-
4 listopada - 17:06: Wydano wersję 0.71-RC0.
-
4 listopada - 18:20: Pierwsze zgłoszenie problemu z kompilacją.
-
4 listopada - 19:45: Społeczność identyfikuje problem.
-
4 listopada - 21:39: Komunikacja obejść, Expo wdraża poprawkę dla wszystkich użytkowników.
-
5 listopada - 03:04: Utworzono nowe zgłoszenie w celu komunikacji statusu i obejść.
-
6 listopada - 16:11: Zgłoszenie do SonaType z prośbą o usunięcie artefaktów.
-
6 listopada - 16:40: Pierwszy tweet z konta @reactnative potwierdzający problem z linkiem do zgłoszenia.
-
6 listopada - 19:05: Decyzja o wydaniu łatki dla wersji React Native aż do 0.63.
-
7 listopada - 00:47: Wydano ostatnią łatkę: 0.63.5.
-
8 listopada - 20:04: Artefakty w Maven Central są w pełni usunięte.
-
10 listopada - 11:51: Zgłoszenie dotyczące incydentu zostało zamknięte.
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.

