Jak osiągnąć płynne przejście z modelu organizacji „jedno duże repozytorium VCS dla wszystkich produktów” do modelu „wielu małych repozytoriów VCS”?

15

Powszechnym scenariuszem jest to, że baza kodu produktu przechowywanego przez w pewnym systemie VCS ewoluuje do tego stopnia, że ​​podstawa kodu może być prawdopodobnie postrzegana jako zawierająca kilka produktów. Podział bazy kodowej na kilka repozytoriów VCS, z których każde dedykowane jest pojedynczemu produktowi, może wykorzystać kilka korzyści (patrz Korzyści z posiadania produktu na repozytorium VCS w porównaniu z modelem repozytorium wzdęcia poniżej). Od strony technicznej podział bazy kodu jest dość łatwym krokiem, ponieważ większość VCS obsługuje tę operację. Podział może jednak powodować problemy inżynieryjne związane z automatycznymi testami, ciągłą dostawą, integracją usług lub monitorowaniem (patrz Problemy zgłaszane przez podział).) Organizacje planujące dokonać takiego podziału muszą zatem wiedzieć, jak przeprowadzić to przejście tak płynnie, jak to możliwe, to znaczy bez przerywania procesu dostarczania i monitorowania. Pierwszym krokiem tego jest prawdopodobnie lepsze zrozumienie pojęcia projektu i jak nakreślić podział w monolitycznej bazie kodu.

W odpowiedziach na te pytania chciałbym zobaczyć:

  1. Próba podania funkcjonalnej definicji tego, czym jest produkt, co daje praktyczne kryteria rzeczywistego wytyczenia produktów w istniejącej bazie kodu.

  2. Zgodnie z tą roboczą definicją opracuj plan, który faktycznie dokonuje podziału. Możemy uprościć założenie, że kodu jest przetwarzana przez w pełni zautomatyzowaną implementującą i . Oznacza to, że każda gałąź jest sprawdzana przez zautomatyzowane oprogramowanie testowe zaimplementowane w bieżącej bazie kodu, a każde połączenie z jakąś „magiczną” gałęzią generuje które są testowane i wdrażane. ( Artefakty produktu to np. Źródłowe pliki archiwów , dokumentacja, binarne pakiety oprogramowania, obrazy Docker , AMI, unikernele).

  3. Taki plan jest satysfakcjonujący, jeśli wyjaśnia, w jaki sposób można go obejść

Problemy podniesione przez podział

  1. Jak zautomatyzowane procedury testowe odnoszą się do wcześniej istniejącego repozytorium monolitycznego i repozytoriów podzielonych?

  2. Jak zautomatyzowane procedury wdrażania odnoszą się do wcześniej istniejącego repozytorium monolitycznego i repozytoriów podzielonych?

  3. Gdzie jest przechowywany kod samych procedur automatycznego wdrażania?

  4. Gdzie są przechowywane , strategie i ?

  5. Jak upewnić się, że programista potrzebuje tylko jednej bazy kodowej na raz (ale możliwe użycie artefaktów z innych baz kodowych).

  6. Jak narzędzie takie jak git-bisect


Uwaga marginalna: Korzyści z posiadania produktu na repozytorium VCS w porównaniu z modelem repozytorium wzdęcia

Posiadanie kilku małych repozytoriów przechowujących bazę kodu dla konkretnego produktu ma następujące zalety w porównaniu z podejściem „repozytorium wzdęć”:

  1. W przypadku repozytorium nadęć trudno jest wycofać wydanie, gdy produkt jest niestabilny, ponieważ historia jest mieszana z inną historią produktu.

  2. W przypadku nadętego repozytorium trudno jest przejrzeć historię projektu lub wycofania, w przypadku małych repozytoriów bardziej prawdopodobne jest przeczytanie tych informacji. (Może to być specyficzne dla VCS, takich jak git, gdzie w przeciwieństwie do svn, nie możemy wyrejestrować poddrzew!)

  3. Z repozytorium wzdęć musimy się rozwijać, kiedy rozwijamy się. Jeśli mamy N repozytoriów, możemy pracować równolegle na N gałęziach, jeśli mamy tylko 1 repozytorium, możemy pracować tylko na jednej gałęzi lub mieć mnóstwo kopii roboczych, które również są kłopotliwe w obsłudze.

  4. W przypadku kilku małych repozytoriów dzienniki przedstawiają mapę cieplną projektu. Mogą być nawet używane jako proxy do rozpowszechniania wiedzy w zespole deweloperów: jeśli nie popełniłem repo X od 3 miesięcy, dobrze byłoby przydzielić mnie do zespołu pracującego nad repo X, aby być na bieżąco z rozwojem w tym komponencie.

  5. Dzięki małym repozytoriom łatwiej jest uzyskać przejrzysty przegląd komponentu. Jeśli wszystko idzie w jednym dużym repozytorium, nie ma żadnego namacalnego artefaktu wyznaczającego każdy element, a baza kodów może łatwo dryfować w kierunku dużej kuli błota .

  6. Małe repozytoria zmuszają nas do pracy nad interfejsami między komponentami. Ale ponieważ chcemy mieć dobrą kapsułkę, i tak powinniśmy to zrobić, więc uznałbym to za zaletę dla małych repozytoriów.

  7. Dzięki kilku małym repozytoriom łatwiej jest mieć kilku właścicieli produktów.

  8. Dzięki kilku małym repozytoriom łatwiej jest mieć proste standardy kodu, które odnoszą się do pełnego repozytorium i które mogą być automatycznie weryfikowane.

Michael Le Barbier Grünewald
źródło
1
Kluczową częścią takiego rozwiązania jest przyzwoite repozytorium artefaktów (np. Artefakt), które pozwala oddzielić komponenty zależne od tego samego repozytorium. IOW zamiast współdzielić kod (jedno repozytorium), publikuj i konsumuj wbudowane biblioteki (artefakty). Jest to również dobre miejsce do rozpoczęcia takiego wysiłku, ponieważ można refaktoryzować / wyodrębniać moduły jeden po drugim.
Assaf Lavie
Z pewnością tak jest. :)
Michael Le Barbier Grünewald
1
Obecnie pracujemy nad bardzo podobnym problemem. Podejście, które rozważamy, to mieć główne repozytorium bez przypisanego do niego kodu i inne repozytoria dołączone jako podmoduły. Ale nadal musimy znaleźć odpowiednie narzędzia i integrację procesu, aby to zrobić. Skomponuję szczegółową odpowiedź, gdy ustalimy szczegóły.
Jiri Klouda
1
Sprawy mogą się nieco bardziej skomplikować, jeśli produkty współużytkują kod (niezależny od platformy / produktu). Lub jeśli istnieje wspólny kod dla rodziny produktów. Nie to, że podział nie byłby dobrym pomysłem, tylko zarządzanie częściami oraz lista zalet i wad byłaby w jakiś sposób inna.
Dan Cornilescu
2
Myślę, że w twojej 6. kuli z git-bisect czegoś brakuje. Zastanawiam się, czy to nie powinno być podzielone na osobne pytania, ponieważ mniej więcej jest to prośba o książkę. Ponieważ definicja produktu jest bardzo subiektywna (i może się różnić), myślę, że w rzeczywistości jest to pytanie od pytania do strony SE. Zbyt szerokie lub zbyt oparte na opiniach.
Tensibai

Odpowiedzi:

9

To fascynujące pytanie, na które prawdziwe odpowiedzi mogą nie istnieć; Doceniam to, że chociaż starałeś się utrzymać kontekst kontekstu na VCS, w naturalny sposób samo skalowało się aż do projektowania infrastruktury i planowania wdrożenia.

Chociaż wydaje się, że wielu z nas pracuje nad tego rodzaju przejściem, które może być ekscytujące, ale jednocześnie tak frustrujące i bolesne; i chciałbym podzielić się moimi doświadczeniami i poglądami, starając się nie być pedantyczny, a tylko dlatego, że nie jestem dobrym inżynierem, nie mogę się też nudzić.

Projekt

Infrastruktura i architektura powinny iść w parze, aby tworzyć nowoczesne oprogramowanie. Mocno połączone, jeśli chcesz. Używanie tych słów może wydawać się dziwne, ale z pewnością nie mówimy tutaj o samym kodzie: to znaczy, że muszą być częścią tego samego schematu. Kiedy przybyły chmury i ludzie zaczęli pisać dla nich oprogramowanie, ilu ludzi wtedy zdało sobie sprawę, że umieszczając tam błotniki, będą po prostu tymi samymi błotnikami w innym miejscu (?) Może kilku myślących naprzód ludzi może to przewidzieć, i prawdopodobnie dzisiaj pracują w devops. Ponieważ devops to tylko modne hasło o tak wielu różnych znaczeniach dla różnych ludzi, widziałem miejsca, w których zespół devops siedziałby na każdym spotkaniu architektury; inne miejsca, w których jest tylko automatyzacja. Aby osiągnąć tego rodzaju transformację, musimy walczyć, aby tam usiąść.

Pewność siebie

Przejście musi być izolowane, w tym sensie, że musi istnieć konsekwentne cięcie historii, które zapewnia samo przejście i tylko siebie, bez żadnych innych zmian (po kilku miesiącach przygotowań). Z jaką pewnością można by to zatwierdzić i nacisnąć czerwony przycisk?

Chodzi mi o to, że podstawa kodu musi się zmienić, aby dostosować się do nowej struktury VCS i bardzo trudno będzie ją scalić podczas opracowywania. (w przypadku tego problemu mogą istnieć strategie ułatwiające, później powiem o wspólnej, która może nieco pomóc w zrównolegleniu rozwoju).

Założę się, że jedynym sposobem jest testowanie behawioralne, a ten sam zestaw testów behawioralnych powinien zostać uruchomiony, aby zweryfikować stary z nową bazą kodu. Nie weryfikujemy, czy aplikacja zachowuje się tutaj zgodnie z oczekiwaniami, ale czy przejście nie zmienia zachowania. Nieudane testy mogą być dobrą rzeczą! Jeśli nadal będą zawieść!

W rzeczywistości bardzo rzadko jest dobrze testowane kula błotna; zwykle kod jest bardzo ściśle powiązany i prawdopodobnie w przypadku większości starszych kodów nie został opracowany przy użyciu metody testowej, nawet testów jednostkowych.

Jeżeli takiego kodu testowego w ogóle brakuje, należy go najpierw napisać.

Strategia

Tak, przejście musi być izolowane; ale jednocześnie zintegrowane. Wiem, że mogę brzmieć tutaj jak szalony, ale nie znalazłem innych słów, aby opisać, jak zaufanie może nadążyć za biznesem. Bardzo niewielu, o ile w ogóle nie ma, firmy chciałyby zaprzestać rozwoju dużej monolitycznej bazy kodu, aby zrobić miejsce dla tej transformacji, a my nie sprawiamy, że dzieje się to w mgnieniu oka. Być może setki programistów mogą stale przyczyniać się do bazy kodu ( użyłbym tu słowa modyfikującego z naszego POV). Podczas gdy nasza praca musi zająć się konkretną migawką, aby zapewnić sobie pewność, musimy się opierać (nie w tym sensie git), aby uniknąć pozostania w tyle na zawsze.

Przedstawiona tutaj strategia wdrażania może dać różne doświadczenia. Typową linią rozwoju jest zawijanie / dostosowywanie (ujawnianie punktów końcowych z opcjonalnie przestawionymi schematami) nowszych gałęzi implementacji (w tym przypadku mieszkających w innych repozytoriach), gdy muszą one wchodzić w interakcje z rdzeniem. Przejście z taką strategią, wraz z refaktoryzacją, może jednocześnie zaoferować scenariusz POC dla przejścia VCS, a następnie krok po kroku. Zobacz to jak wyrzeźbienie kuli błota. Tak, życie oferuje wiele zabawniejszych rzeczy.

Dług techniczny

Sfery zarządzania przedsiębiorstwem zaczęły rozumieć dług techniczny i brać go pod uwagę. Nie, podrap to, nieprawda. Podczas gdy coraz bardziej powszechne jest zbieranie danych pomiarowych i jakościowych, w zakresie analizy kodu statycznego, przeglądu kodu, wyników testów behawioralnych i wydajności, a także generowania ładnych raportów i wszystkiego ... nadal niezwykle trudno jest sprawić, aby firma zaakceptowała ciągłość podejście do refaktoryzacji. Wartość biznesowa tego. „Podążamy sprawnym procesem, a to nie wprowadzi żadnych ulepszeń do funkcji, prawda?” . Zasadniczo, robiąc to, negują istnienie długu technicznego. Widzę to jako często brakujący niezbędny krok, aby móc rozpocząć dowolne przejście od architektury monolitu do architektury mikrousług.

Ponowna agregacja

Po tym wszystkim możesz nadal chcieć udostępnić pojedynczy widok podobny do repozytorium, w którym możesz zbudować więcej niż jeden produkt. Z dowolnego powodu, tj. Curr / next release, multibrand, builds build. Narzędzia takie jak Google Repo mogą w tym przypadku pomóc. Sam nigdy go nie użyłem, ale wiem, że będę potrzebował jednego dnia.

Testy integracyjne

W przypadku mikrousług testowanie integracyjne zakłada inny kontekst „testowania własnego API”. Wyższe warstwy testowania, funkcjonalne lub wydajnościowe, mogą istnieć i będą istnieć, ale czy znaczą wiele bez odpowiedniego testowania integracji? To byłoby jak testowanie integracyjne bez testów jednostkowych. Oczywiście nie. Dlatego, jeśli potrzebujesz git bisecta, wykonasz go w gałęzi repozytorium mikrousług, zapomnij o uruchomieniu go w repozytorium mudball.

PS. to jest szkic, mój angielski jest zły i naprawię go pewnego dnia

ᴳᵁᴵᴰᴼ
źródło