Obsługa wielu oddziałów w ciągłej integracji


85

Miałem do czynienia z problemem skalowania CI w mojej firmie i jednocześnie próbując dowiedzieć się, jakie podejście przyjąć, jeśli chodzi o CI i wiele oddziałów. Podobne pytanie pojawia się przy przepełnieniu stosu, wielu gałęziach funkcji i ciągłej integracji . Zacząłem nowy, ponieważ chciałbym uzyskać więcej dyskusji i przedstawić analizę pytania.

Do tej pory odkryłem, że są 2 główne podejścia, które mogę zastosować (a może inne ???).

Wygląda więc na to, że jeśli chcę zapewnić programistom CI dla ich własnych niestandardowych gałęzi, potrzebuję specjalnego narzędzia dla Jenkinsa (API lub skryptów powłoki czy coś takiego?) I obsługiwać skalowanie. Albo mogę im powiedzieć, aby częściej łączyli się z DEV i żyli bez CI w niestandardowych gałęziach. Którą byś wybrał, czy są inne opcje?

Odpowiedzi:


69

Kiedy mówisz o skalowaniu CI, tak naprawdę mówisz o skalowaniu wykorzystania twojego serwera CI do obsługi wszystkich gałęzi funkcji wraz z linią główną. Początkowo wygląda to na dobre podejście, ponieważ programiści w oddziale uzyskują wszystkie zalety automatycznego testowania, które obejmują zadania CI. Jednak napotykasz problemy z zarządzaniem zadaniami serwera CI (jak odkryłeś), a co ważniejsze, tak naprawdę nie robisz CI. Tak, używasz serwera CI, ale nie integrujesz w sposób ciągły kodu od wszystkich swoich programistów.

Wykonywanie prawdziwego CI oznacza, że ​​wszyscy twoi programiści regularnie angażują się w główną linię. Łatwo powiedzieć, ale najtrudniejsze jest zrobienie tego bez przerywania aplikacji. Zdecydowanie zalecam zapoznanie się z sekcją Ciągłe dostarczanie , a zwłaszcza sekcją Utrzymywanie dostępności aplikacji w rozdziale 13: Zarządzanie składnikami i zależnościami . Główne punkty to:

  • Ukryj nową funkcję, dopóki nie zostanie zakończona (AKA Feature Toggles ).
  • Wszystkie zmiany należy wprowadzać stopniowo jako serię małych zmian, z których każda jest dostępna do wydania.
  • Użyj rozgałęzienia według abstrakcji, aby wprowadzić zmiany na dużą skalę w bazie kodu.
  • Użyj komponentów, aby oddzielić części aplikacji, które zmieniają się w różnym tempie.

Są dość oczywiste, z wyjątkiem rozgałęzień według abstrakcji. To jest tylko wymyślne określenie:

  1. Utwórz abstrakcję dotyczącą części systemu, którą chcesz zmienić.
  2. Przebuduj resztę systemu, aby użyć warstwy abstrakcji.
  3. Utwórz nową implementację, która nie będzie częścią ścieżki kodu produkcyjnego, dopóki nie zostanie zakończona.
  4. Zaktualizuj warstwę abstrakcji, aby delegować ją do nowej implementacji.
  5. Usuń starą implementację.
  6. Usuń warstwę abstrakcji, jeśli nie jest już odpowiednia.

Następujący akapit z sekcji Oddziały, strumienie i ciągła integracja w rozdziale 14: Zaawansowana kontrola wersji podsumowuje skutki.

Podejście przyrostowe z pewnością wymaga większej dyscypliny i troski - a nawet więcej kreatywności - niż tworzenie oddziału i nurkowanie w celu przeprojektowania i opracowania nowej funkcjonalności. Jednak znacznie zmniejsza to ryzyko, że zmiany zepsują aplikację i zaoszczędzi Tobie i Twojemu zespołowi dużo czasu na scalanie, naprawianie awarii i wprowadzanie aplikacji w stan umożliwiający wdrożenie.

Porzucenie gałęzi funkcji wymaga sporej zmiany umysłu, a zawsze pojawi się opór. Z mojego doświadczenia wynika, że ​​ten opór jest oparty na tym, że programiści nie czują się bezpiecznie, wprowadzając kod do głównej linii i jest to rozsądna obawa. To z kolei zwykle wynika z braku wiedzy, pewności lub doświadczenia z technikami wymienionymi powyżej oraz prawdopodobnie z braku pewności co do testów automatycznych. Ten pierwszy można rozwiązać dzięki szkoleniom i wsparciu programistów. Ten ostatni jest znacznie trudniejszym problemem do rozwiązania, jednak rozgałęzianie nie zapewnia żadnego dodatkowego rzeczywistego bezpieczeństwa, po prostu odkłada problem, dopóki programiści nie poczują się wystarczająco pewni swojego kodu.


4
Tom, działa to dobrze tylko wtedy, gdy 1) zarówno wydanie, jak i aktualizacja są stosunkowo łatwe 2) większość twoich zmian jest dobrze odizolowana. Dotyczy to twórców stron internetowych, ale jeśli tworzysz wersje pudełkowe, wersje stabilne muszą pozostać stabilne za wszelką cenę, ponieważ poprawki są naprawdę drogie lub nawet niemożliwe w dużym środowisku korporacyjnym.
Jevgeni Kabanov

13
prawdziwy CI to nie tylko integracja, ale także sprzężenie zwrotne
Anton Arhipov,

3
Wybrałem to jako odpowiedź (przynajmniej przyznałem nagrodę, daj mi znać, jeśli w jakiś sposób nadal muszę to oznaczyć jako poprawne), ale myślę, że to nie jest rozwiązanie mojego problemu. Napisałem komentarz
toomasr

1
@Jevgeni Kabanov i @toomasr Oboje wydajecie się zakładać, że robienie prawdziwego CI oznacza rezygnację z jakości i działa to tylko w przypadku twórców stron internetowych, ponieważ tak łatwo jest wypychać poprawki. Domyślam się, że martwisz się o podejrzane popełnienie tuż przed wydaniem. Tak, może to spowodować złe wydanie, którego naprawienie może być kosztowne. Jednak podejrzane zatwierdzenie na gałęzi funkcji tuż przed jej wydaniem jest równie złe. Jeśli uważasz, że istnieje różnica, podziel się uzasadnieniem. Jednym ze sposobów rozwiązania tego problemu (jeśli zatwierdzenie dotyczyło głównej linii lub gałęzi funkcji) jest użycie podejścia Continuous Delivery.
Tom Howard

1
Aha, i tak przy okazji, przez ostatnie 4 lata moje główne doświadczenie w zakresie rozwoju zdobywałem w instytucjach finansowych. Konieczność posiadania stabilnych wydań i koszt popełnienia błędu (nie wspominając o procesie kontroli zmian, przez który trzeba przejść, aby wypchnąć poprawkę) nie są dużo większe. Produkt w pudełku byłby dla mnie relaksującą odmianą.
Tom Howard

4

Utworzyłbym osobne zadania dla każdego oddziału. Zrobiłem to już wcześniej i nie jest trudno zarządzać i skonfigurować, jeśli poprawnie skonfigurowałeś Hudson / Jenkins. Szybkim sposobem na utworzenie wielu zadań jest skopiowanie z istniejącego zadania o podobnych wymaganiach i zmodyfikowanie ich w razie potrzeby. Nie jestem pewien, czy chcesz pozwolić każdemu deweloperowi na skonfigurowanie własnych zadań dla własnych oddziałów, ale nie jest to dużo pracy dla jednej osoby (np. Menedżera budowy). Po połączeniu niestandardowych gałęzi w stabilne gałęzie, odpowiednie zadania można usunąć, gdy nie są już potrzebne.

Jeśli martwisz się o obciążenie serwera CI, możesz skonfigurować oddzielne instancje CI lub nawet oddzielne slave'y, aby pomóc zrównoważyć obciążenie na wielu serwerach. Upewnij się, że serwer, na którym uruchamiasz Hudson / Jenkins, jest odpowiedni. Użyłem Apache Tomcat i po prostu musiałem upewnić się, że ma wystarczającą ilość pamięci i mocy obliczeniowej, aby przetworzyć kolejkę kompilacji.

Ważne jest, aby jasno określić, co chcesz osiągnąć za pomocą CI, a następnie wymyślić sposób na jego wdrożenie bez dużego wysiłku ręcznego lub powielania. Nie ma nic złego w korzystaniu z innych zewnętrznych narzędzi lub skryptów wykonywanych przez serwer CI, które pomagają uprościć ogólny proces zarządzania kompilacją.


Myślę, że ten brak narzędzi oznacza, że ​​w tym dziale jest miejsce na niektóre wtyczki / produkty. Nie chciałbym pisać własnych.
toomasr

1
Istnieje narzędzie dla Jenkinsa, które automatycznie tworzy konfigurację kompilacji dla każdej gałęzi: entagen.github.com/jenkins-build-per-branch
kolen

3

Wybrałbym dev + stabilne gałęzie. A jeśli nadal chcesz własnych oddziałów i boi się obciążeniem, to dlaczego nie przenieść te niestandardowe te do chmury i niech programiści zarządzać samodzielnie, np http://cloudbees.com/dev.cb Jest to firma, w której jest teraz Kohsuke . Istnieje również narzędzie Eclipse, więc jeśli korzystasz z Eclipse, będziesz mieć je ściśle zintegrowane z dev env.


Czy zamieniam brak narzędzi do zarządzania wieloma oddziałami na ten sam problem, ale w chmurze? Chodzi mi o to, że będę mógł teraz zarządzać obciążeniem, ale nadal nie będę w stanie obsługiwać gałęzi?
toomasr

Chodziło mi o to, by zapomnieć o narzędziach i rozdzielić zarządzanie wśród programistów - „jeśli chcesz mieć niestandardową wersję osobistą, oto twoje konto CB”. Bez wpływu na wydajność kompilacji głównego serwera. Chociaż ich API jest dość proste, więc tworzenie narzędzi do zarządzania prawdopodobnie zajęłoby jedno-dwa tygodnie, a potem robisz, co chcesz. Jak to w życiu bywa, jeśli chcesz czegoś wyjątkowego, lepiej zrób to sam. Jednocześnie szybko się rozwijają i słuchają społeczności, więc wypełnij prośbę o funkcję i może się wkrótce pojawi.
Anton Safonov,

Och, zrozumiałem. Poinformuj właściciela oddziału, aby wybrał interesujące go zadania i skonfigurował je dla swojego oddziału niestandardowego według własnego uznania. Podoba mi się ten pomysł.
toomasr

1

Właściwie to, co jest naprawdę problematyczne, to budowanie izolacji z gałęziami funkcji. W naszej firmie mamy zestaw oddzielnych projektów maven, które są częścią większej dystrybucji. Te projekty są obsługiwane przez różne zespoły, ale dla każdej dystrybucji wszystkie projekty muszą zostać zwolnione. Odgałęzienie funkcji może teraz nakładać się z jednego projektu na inny, a wtedy izolacja kompilacji staje się bolesna. Wypróbowaliśmy kilka rozwiązań:

  • utwórz oddzielne repozytoria migawek w nexusie dla każdej gałęzi funkcji
  • udostępniać lokalne repozytoria na dedykowanych niewolnikach
  • użyj wtyczki repository-server-plugin z repozytoriami zewnętrznymi
  • buduj wszystko w ramach jednego zadania z jednym prywatnym repozytorium

Właściwie to ostatnie rozwiązanie jest najbardziej obiecujące. Wszystkim innym rozwiązaniom brakuje w ten czy inny sposób. Wraz z wtyczką job-dsl można łatwo skonfigurować nową gałąź funkcji. po prostu skopiuj i wklej świetny skrypt, dostosuj gałęzie i pozwól, aby zadanie seed utworzyło nowe zadania. Upewnij się, że zadanie inicjujące usuwa zadania niezarządzane. Następnie możesz łatwo skalować za pomocą gałęzi funkcji w różnych projektach maven.

Ale jak powiedział wyżej Tom, przyjemniej byłoby przezwyciężyć konieczność rozgałęzień funkcji i nauczyć programistów czystej integracji, ale jest to dłuższy proces, a wynik nie jest jasny w przypadku wielu starszych części systemu, których już nie będziesz dotykać.

moje 2 centy

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.