Rozgałęzienie przerywa ciągłą integrację?

18

Myślę, że ten artykuł, Udany model rozgałęziania gitów , jest bardzo dobrze znany wśród doświadczonych użytkowników DVCS.

Używam hggłównie, ale uważam, że ta dyskusja jest odpowiednia dla każdego DVCS.

Nasz obecny obieg pracy polega na tym, że każdy programista klonuje główne repozytorium. Piszemy kod na naszym lokalnym repozytorium, przeprowadzamy testy, a jeśli wszystko pójdzie dobrze, wypychamy do mastera.

Chcemy więc skonfigurować serwery CI, takie jak Jenkins, i ulepszyć nasz przepływ pracy z przyszłym systemem udostępniania (szef kuchni, lalek, ansible itp.).

Prawdziwa część

Cóż, powyższy model działa dobrze, ale gałęzie mogą złamać CI. Gałąź funkcji powinna zsynchronizować się z początkiem (zgodnie z artykułem byłoby to developmentgałąź), aby CI i scalanie były płynne, prawda?

Powiedzmy, że Alice i Bob pracują nad dwiema funkcjami. Ale Alice jest skończona następnego dnia. Funkcja Boba trwa tydzień. Do czasu, gdy Bob jest skończony, jego zmiany są przestarzałe (być może Alice zmieniła / zmieniła nazwy niektórych klas).

Jedno rozwiązanie polega na tym, że programiści muszą codziennie master/originsprawdzać, czy są jakieś zmiany. Jeśli Alice się zaangażuje, Bob powinien pociągnąć i połączyć się ze swoim obszarem roboczym, aby jego gałąź funkcji była aktualna.

  1. Czy to dobry sposób?
  2. Czy te gałęzie powinny istnieć w głównym repozytorium (nie lokalnym klonie?) Czy to znaczy, że każdy programista powinien mieć uprawnienia do głównego repozytorium na GitHub / Bitbucket, aby móc utworzyć nowy oddział? Czy odbywa się to lokalnie?
  3. Wreszcie model przedstawiony w artykule powinien przerwać CI, jeśli gałęzie nie są zsynchronizowane z origin/master. Skoro chcemy tworzyć kompilację nocną, czy programiści powinni pobierać i scalać przed wyjściem z pracy, a także uruchamiać CI w każdej gałęzi funkcji?
CppLearner
źródło

Odpowiedzi:

12

Przede wszystkim użycie gałęzi funkcji (w celu odizolowania pracy wykonanej nad funkcją) i CI (w celu znalezienia problemów z integracją od razu po ich zatwierdzeniu) są nieco sprzeczne.

Moim zdaniem uruchomienie CI w gałęziach funkcji jest stratą czasu. Ponieważ gałęzie funkcji przychodzą i odchodzą często, narzędzia CI trzeba będzie ciągle konfigurować. I to w przypadku oddziału, który najprawdopodobniej otrzymuje aktualizacje tylko z jednego lub dwóch źródeł, które koordynują swoje zameldowania, aby uniknąć problemów, które system CI powinien wykryć.
Dlatego też nie ma sensu, aby gałęzie funkcji znajdowały się na głównym serwerze repozytorium.

Jeśli chodzi o pytania 1 i 3: deweloper jest odpowiedzialny za zapewnienie, że kompilacja na głównej gałęzi programistycznej nie ulegnie awarii, gdy połączą z nią swoją gałąź funkcji. Sposób, w jaki to robią, jest ich problemem, ale są dwa możliwe sposoby:

  • Regularnie wprowadzaj zmiany dokonane w głównej gałęzi programistycznej do gałęzi funkcji (np. Codziennie)
  • Po zakończeniu operacji połącz główną gałąź programistyczną z gałęzią funkcji i prześlij wynik scalania na główną gałąź programistyczną.

W obu przypadkach oczywiste problemy z integracją (np. Zmienione nazwy klas / plików) zostają znalezione i naprawione najpierw w gałęzi funkcji. Bardziej subtelne problemy występują najprawdopodobniej tylko wtedy, gdy uruchomiona jest kompilacja nocna i należy ją tam naprawić.

Bart van Ingen Schenau
źródło
Zgadzam się, że użycie gałęzi funkcji jest (nieznacznie) sprzeczne z koncepcją CI. Jednakże, jest możliwe stworzenie systemu CI, który nie wymaga rekonfiguracji do pracy na oddziałach fabularnych. (Robiłem to w przeszłości z kilkoma prostymi skryptami Pythona) i może to być przydatne, gdy twoje gałęzie „funkcji” są faktycznie używane jako gałęzie stabilizacji wersji, gdzie CI jest absolutnie wymagane.
William Payne,
1
Właściwie uważam, że potrzebujemy dwóch „centralnych” gałęzi - jednej jako gałęzi „throwaway_integration”, która istnieje wyłącznie jako szybkie sprawdzanie scalania i testowania aktywnie rozwijanych funkcji, oraz kolejna gałąź „master” lub „stabilna”, która zawiera funkcje po osiągnięciu pewnego poziomu stabilności / dojrzałości. Programiści ściągają stabilny kod do pracy z drugiej gałęzi „stabilnej” / „głównej”, a także często łączą i wypychają zmiany do pierwszej gałęzi „niestabilnej” / „throwaway_integration”. Testy CI powinny oczywiście działać na obu gałęziach.
William Payne,
@WilliamPayne: Uważam, że taka „niestabilna” gałąź jest często nazywana „rozwijającą się”
Bart van Ingen Schenau
5

W odpowiedzi na 1)

Każdy sposób, który działa, jest dobrym sposobem. Jednak : cała zasada ciągłej integracji polega na ciągłej integracji . Chodzi o to, aby wychwycić błędy integracyjne nie tylko tak wcześnie, jak to możliwe, ale w cyklu sprzężenia zwrotnego programowania - tj. Gdy wszystkie szczegóły dotyczące testowanego kodu znajdują się w pamięci krótkoterminowej programisty dokonującego zmian. Oznacza to, że w normalnych, codziennych okolicznościach praca musi być zintegrowana między gałęziami funkcji przy każdym zatwierdzeniu - może raz na około 15 minut. Powtórzmy: Głównym celem ciągłej integracji jest ujawnienie błędów integracji, podczas gdy wszystkie szczegóły znajdują się w pamięci krótkoterminowej programistów dokonujących zmian.

2)

Przeważnie gałęzie są tworzone w Mercurial poprzez klonowanie repozytoriów, więc nie trzeba przyznawać każdemu deweloperowi uprawnień do zatwierdzania głównego repozytorium. Prawdopodobnie jednak chcesz dać programistom możliwość tworzenia sklonowanych repozytoriów na serwerze ciągłej integracji, ponieważ nie zawsze jest możliwe wykonanie testów lokalnie. (Kiedyś miałem system CI, w którym testy jednostkowe trwały 8 godzin na 128-rdzeniowym klastrze) - Nie trzeba dodawać, że programiści nie, nie mogli uruchomić testów lokalnie.

3)

Jeśli masz do tego zasoby obliczeniowe, tak, programiści powinni być w pełni na bieżąco z główną linią programowania, szczególnie przed wyjściem z pracy, i powinieneś uruchomić testy na noc na wszystkich liniach programowania (chociaż większość systemów CI nie ułatwiaj tego).

William Payne
źródło
1
„Przeważnie gałęzie są tworzone w Mercurial poprzez klonowanie repozytoriów” - mogło tak być w 2013 r., Ale w dzisiejszych czasach zakładki Mercurial są funkcjonalnie równoważne z gałęziami Git we wszystkim oprócz nazwy.
Kevin
@Kevin: Najprawdopodobniej masz rację. Używam git (prawie) wyłącznie od lutego 2013 r. - około miesiąc po napisaniu powyższej odpowiedzi ... więc nie jestem szczególnie na bieżąco o tym, jakie zmiany zaszły w Mercurial od tego czasu.
William Payne,
1

Oto, jak możesz to zrobić: rozgałęzianie funkcji.

  1. Dla każdego nowego zadania ( poprawka błędu , funkcja itp.) Uruchom nową gałąź (np. Bugfix-ticket123-the_thingie_breaks)
  2. Podczas pracy stale aktualizuj i scal domyślny (lub master w git) z gałęzią funkcji . Pomaga to w aktualizacji oddziału bez konieczności pracy w oddziale domyślnym
  3. Kiedy twoja funkcja jest gotowa i testy jednostkowe przejdą pomyślnie , a następnie ponownie pociągnij i połącz domyślnie z gałęzią, zamknij gałąź i pchnij ją bez scalania , integrator zauważy nową głowę i że jest to gałąź zamknięta, więc on / ona zajmie się jego integracją. Jeśli nie masz integratora, przełącz się na domyślny i połącz gałąź funkcji w domyślną .

Ważną rzeczą jest to, że podczas łączenia gałęzi funkcji będziesz mieć 0 konfliktów w domyślnej gałęzi, a wszystkie testy przejdą pomyślnie .

Dzięki temu prostemu przepływowi pracy zawsze będziesz mieć nieskazitelną i stabilną gałąź domyślną, teraz zrób to samo dla gałęzi wydania, ale integruj z domyślnej . Jeśli potrzebujesz zintegrować poprawki bezpośrednio z gałęziami wydania, możesz to zrobić, pomijając gałąź domyślną, ale ponownie wybieraj tylko te gałęzie, które właśnie zaktualizowały się z gałęzi docelowej i nie mają żadnych konfliktów, a ich testy jednostkowe przebiegają pomyślnie.

dukeofgaming
źródło
Miksujesz i zamieniasz raczej ortogonalne rzeczy. 0 konflikt scalania! = 0 wadliwy test jednostkowy, udane scalenie! = Kod udany
Lazy Badger
Dodano wyjaśnienie, zapomniałem wspomnieć, że testy jednostkowe również powinny przejść pozytywnie :)
dukeofgaming