Pracuję nad bardzo dużym projektem open source prowadzonym przez badania, z udziałem wielu innych regularnych współpracowników. Ponieważ projekt jest obecnie dość duży, konsorcjum (złożone z dwóch pełnoetatowych pracowników i kilku członków) odpowiada za utrzymanie projektu, ciągłą integrację (CI) itp. Po prostu nie mają czasu na integrację zewnętrznych wkłady.
Projekt składa się z „podstawowego” frameworka, zawierającego około pół miliona wierszy kodu, wiązki „wtyczek” utrzymywanych przez konsorcjum oraz kilku zewnętrznych wtyczek, z których większość nie jest nawet zdaje sobie z tego sprawę.
Obecnie nasz CI buduje rdzeń i utrzymywane wtyczki.
Jednym z dużych problemów, przed którymi stoimy, jest to, że większość współpracowników (a zwłaszcza okazjonalnych) nie buduje 90% utrzymywanych wtyczek, więc kiedy proponują zmiany w rdzeniu (które obecnie zdarzają się dość regularnie), sprawdzili, czy kod kompiluje się na ich komputerze przed wysłaniem żądania ściągania w GitHub.
Kod działa, są szczęśliwi, a następnie CI kończy budowanie i zaczynają się problemy: kompilacja nie powiodła się w utrzymywanej przez konsorcjum wtyczce, której współtwórca nie zbudował na swoim komputerze.
Ta wtyczka może zależeć od bibliotek stron trzecich, takich jak na przykład CUDA , a użytkownik nie chce, nie wie, jak, lub po prostu nie może z powodów sprzętowych, skompilować tej uszkodzonej wtyczki.
Tak więc - albo pobyty PR ad aeternam w otchłań nie-do-połączyły PRS - Albo specjalista greps przemianowaną zmienną w źródle łamanego plugin zmienia Kodeksu naciska na jego / jej oddziału, czeka na CI, aby zakończyć kompilację, zwykle dostaje więcej błędów i powtarza proces, dopóki CI nie będzie zadowolony - Lub jeden z dwóch już przepełnionych stałych konsorcjów podaje rękę i próbuje naprawić PR na swoim komputerze.
Żadna z tych opcji nie jest wykonalna, ale po prostu nie wiemy, jak to zrobić inaczej. Czy kiedykolwiek spotkałeś się z podobną sytuacją swoich projektów? A jeśli tak, jak poradziłeś sobie z tym problemem? Czy istnieje rozwiązanie, którego tu nie widzę?
źródło
Odpowiedzi:
Rozwój oparty na CI jest w porządku! Jest to o wiele lepsze niż brak uruchamiania testów i włączanie uszkodzonego kodu! Jest jednak kilka rzeczy, które mogą to ułatwić wszystkim zaangażowanym:
Określ oczekiwania: przygotuj dokumentację dotyczącą wkładu, która wyjaśnia, że CI często znajduje dodatkowe problemy i że będą musiały zostać naprawione przed scaleniem. Być może wyjaśnij, że małe, lokalne zmiany są bardziej prawdopodobne, że dobrze się sprawdzi - więc podzielenie dużej zmiany na wiele PR może być rozsądne.
Zachęcaj do testowania lokalnego: Ułatw konfigurację środowiska testowego dla swojego systemu. Skrypt weryfikujący, czy wszystkie zależności zostały zainstalowane? Kontener Docker, który jest gotowy do pracy? Obraz maszyny wirtualnej? Czy Twój tester ma mechanizmy, które pozwalają na ważniejsze testy?
Wyjaśnij, jak używać CI dla siebie: Częścią frustracji jest to, że ta informacja zwrotna pojawia się dopiero po przesłaniu PR. Jeśli współautorzy skonfigurują CI dla swoich własnych repozytoriów, otrzymają wcześniejsze opinie i wygenerują mniej powiadomień CI dla innych osób.
Rozwiąż wszystkie PR, tak czy inaczej: Jeśli czegoś nie można scalić, ponieważ jest zepsute, i jeśli nie ma postępu w usuwaniu problemów, po prostu go zamknij. Te porzucone otwarte PR po prostu zaśmiecają wszystko, a każda informacja zwrotna jest lepsza niż ignorowanie problemu. Można to bardzo ładnie sformułować i wyjaśnić, że chętnie się połączysz, gdy problemy zostaną naprawione. (patrz także: Sztuka zamknięcia przez Jessie Frazelle , Najlepsze praktyki dla konserwatorów: nauka odmawiania )
Zastanów się również, czy te opuszczone PR są możliwe do wykrycia, aby ktoś inny mógł je odebrać. Może to być nawet dobre zadanie dla nowych autorów, jeśli pozostałe problemy są bardziej mechaniczne i nie wymagają głębokiej znajomości systemu.
W perspektywie długoterminowej zmiany wydają się łamać niepowiązaną funkcjonalność tak często, że może to oznaczać, że twój obecny projekt jest nieco problematyczny. Na przykład, czy interfejsy wtyczek poprawnie obudowują elementy wewnętrzne twojego rdzenia? C ++ ułatwia przypadkowe wyciekanie szczegółów implementacji, ale umożliwia także tworzenie silnych abstrakcji, których bardzo trudno użyć niewłaściwie. Nie możesz tego zmienić w ciągu nocy, ale możesz poprowadzić długoterminową ewolucję oprogramowania w kierunku mniej delikatnej architektury.
źródło
Budowanie trwałego modelu wtyczek wymaga, aby Twoja podstawowa struktura udostępniała stabilny interfejs, na którym mogą polegać wtyczki. Złotą zasadą jest to, że możesz z czasem wprowadzać nowe interfejsy, ale nigdy nie możesz modyfikować już opublikowanego interfejsu. Jeśli zastosujesz się do tej zasady, możesz refaktoryzować implementację podstawowego frameworka bez obawy przypadkowego zerwania wtyczek, niezależnie od tego, czy jest to konsorcjum, czy zewnętrzne.
Z tego, co opisałeś, wygląda na to, że nie masz dobrze zdefiniowanego interfejsu, co utrudnia stwierdzenie, czy zmiana spowoduje uszkodzenie wtyczek. Pracuj nad zdefiniowaniem tego interfejsu i nadaniem mu wyraźnego charakteru w swojej bazie kodu, aby współautorzy wiedzieli, czego nie powinni modyfikować.
źródło
Szczerze mówiąc, nie sądzę, że można sobie z tym poradzić w lepszy sposób - jeśli zmiany spowodują uszkodzenie utrzymywanych części projektu, CI powinien zawieść.
Czy twój projekt ma
contributing.md
coś podobnego, aby pomóc nowym i okazjonalnym współpracownikom w przygotowaniu swojego wkładu? Czy masz jasną listę, które wtyczki są częścią rdzenia i muszą pozostać kompatybilne?Jeśli trudno jest zbudować wszystko na komputerze z powodu zależności itp., Możesz pomyśleć o tworzeniu gotowych do użycia obrazów dokerów jako środowisk kompilacji, z których będą mogli korzystać współtwórcy.
źródło
Myślę więc, że tutaj może upaść luźny styl projektów open source; większość centralnie zorganizowanych projektów jest ostrożna w zakresie refaktoryzacji rdzenia, szczególnie gdy przekracza ona granicę API. Jeśli dokonają refaktoryzacji granicy interfejsu API, zwykle jest to „wielki wybuch”, w którym wszystkie zmiany są planowane jednocześnie z przyrostem głównej wersji interfejsu API, a stary interfejs API zostaje zachowany.
Proponuję zasadę „wszystkie zmiany API muszą być planowane z wyprzedzeniem”: jeśli pojawi się PR, który spowoduje cofnięcie niezgodnej wstecz do API, ktoś, kto nie był w kontakcie z opiekunami, z góry zgodził się na ich podejście, po prostu się zamyka i zgłaszający wskazuje na regułę.
Będziesz także potrzebował jawnej wersji interfejsu API wtyczki. Umożliwia to tworzenie wersji 2, podczas gdy wszystkie wtyczki w wersji 1 nadal się budują i działają.
Chciałbym również zadać trochę więcej pytania, dlaczego wprowadzono tak wiele podstawowych zmian refaktoryzacji i zmian API. Czy są naprawdę potrzebni, czy po prostu ludzie narzucają projekt osobisty gust?
źródło
Wygląda na to, że proces CI musi być ściślejszy, bardziej kompleksowy i bardziej widoczny dla autorów, zanim podniosą PR. Na przykład BitBucket ma funkcję potoków, która pozwala na to, gdy dajesz mu plik, który definiuje w kodzie proces kompilacji CI, a jeśli się nie powiedzie, gałąź nie zostanie scalona.
Bez względu na technologię, automatyczne kompilacje, gdy współtwórca przesyła się do oddziału, dadzą im znacznie szybsze informacje zwrotne na temat tego, na co należy zwracać uwagę podczas wprowadzania zmian i doprowadzą do PR, które nie wymagają naprawy po fakcie.
Problemy projektowe dobrze byłoby naprawić, ale są prostopadłe do tego problemu.
źródło
Twoje rozwiązanie jest proste: obniż barierę wkładu .
Najprostszym sposobem (1) przyspieszenia cyklu edycji-kompilacji-testu oraz (2) płynnego różnicowania środowiska jest zapewnienie serwerów kompilacji :
A następnie otwórz te serwery kompilacji dla współpracowników. Powinni mieć możliwość zdalnego zalogowania się na nowym obrazie Docker oraz zdalnej edycji-testu-kompilacji na tym komputerze.
Następnie:
Ogólnie rzecz biorąc, serwery kompilacji mogą być współużytkowane przez wielu współautorów, jednak gdy zaangażowane są specjalne sprzętowe urządzenia peryferyjne, może być konieczne, aby współtwórca sam używał wspomnianych urządzeń peryferyjnych.
Źródło: pracując nad oprogramowaniem wykorzystującym układy FPGA, biorąc pod uwagę cenę bestii i różnorodność modeli, których potrzebujemy, nie znajdziesz każdego modelu układu FPGA zainstalowanego na każdym komputerze dewelopera.
źródło
Jeśli wkład w rdzeń bez zmiany jakiejkolwiek umowy może spowodować uszkodzenie oprogramowania zależnego, sugeruje to, że:
Oba problemy powinny być łatwe do rozwiązania, ale wspominasz, że zespół podstawowy może nie mieć takiej możliwości. Jedną z opcji byłoby zwrócenie się do społeczności o pomoc w rozwiązaniu problemu.
źródło
Wydaje się, że nikt inny nie podniósł tego jako potencjalnego rozwiązania.
Podczas opracowywania rdzenia zachęcaj programistów do uruchamiania testów zgodności. Jeśli się nie uda, nie melduj się.
Nie zapewni to w 100% zgodności, ale wcześnie wykryje o wiele więcej problemów.
Druga korzyść polega na tym, że nagrania te mogą podkreślać, które interfejsy są aktywnie używane i jakie funkcje są aktywnie używane.
źródło
Mam problem ze zrozumieniem obecnej sytuacji: CI buduje tylko jedną gałąź?
Czy istnieje powód, dla którego nie można zbudować więcej niż jednego oddziału za pomocą CI?
Najprostszym rozwiązaniem tego problemu byłoby umożliwienie każdemu współpracownikowi uruchomienia kompilacji CI w jego / jej gałęzi funkcji .
Następnie po prostu potrzebujesz udanej kompilacji CI w gałęzi funkcji, aby zaakceptować żądanie ściągnięcia tej gałęzi.
źródło