Obecnie mamy jedną gałąź główną dla naszej aplikacji PHP we wspólnym repozytorium. Mamy ponad 500 klientów, którzy są subskrybentami naszego oprogramowania, z których większość ma pewne dostosowania do różnych celów, każdy w oddzielnym oddziale. Dostosowaniem może być inna nazwa pola tekstowego, zupełnie nowa funkcja lub moduł albo nowe tabele / kolumny w bazie danych.
Wyzwanie, przed którym stoimy, polega na tym, że utrzymując setki niestandardowych oddziałów i dystrybuując je do klientów, od czasu do czasu udostępniamy nowe funkcje i aktualizujemy nasz oddział główny, a my chcemy przekazywać zmiany gałęzi master do oddziałów niestandardowych w celu aktualizacji je do najnowszej wersji.
Niestety często powoduje to wiele konfliktów w kodzie niestandardowym i spędzamy wiele godzin, przeglądając każdą gałąź, aby rozwiązać wszystkie konflikty. Jest to bardzo nieefektywne i stwierdziliśmy, że błędy nie są rzadkie przy rozwiązywaniu tych konfliktów.
Szukam bardziej wydajnego sposobu na aktualizowanie naszych gałęzi wydań klienta do gałęzi głównej, co przyniesie mniej wysiłku podczas łączenia.
źródło
Odpowiedzi:
Całkowicie nadużywasz gałęzi! Dostosowanie powinno być oparte na elastyczności aplikacji, a nie elastyczności kontroli wersji (która, jak odkryłeś, nie jest przeznaczona / przeznaczona do tego rodzaju zastosowań).
Na przykład, aby etykiety pól tekstowych pochodziły z pliku tekstowego, a nie były zakodowane na stałe w aplikacji (w ten sposób działa internacjonalizacja). Jeśli niektórzy klienci mają różne funkcje, uczyń swoją aplikację modułową , z surowymi wewnętrznymi granicami regulowanymi przez rygorystyczne i stabilne interfejsy API, aby funkcje można było podłączyć w razie potrzeby.
Podstawowa infrastruktura i wszelkie wspólne funkcje muszą być przechowywane, konserwowane i testowane tylko raz .
Powinieneś to zrobić od samego początku. Jeśli masz już pięćset wariantów produktu (!), Naprawienie go będzie ogromną pracą… ale nie więcej niż bieżącą konserwacją.
źródło
Posiadanie 500 klientów to miły problem, jeśli spędziłeś czas z góry, aby uniknąć tego problemu z oddziałami, być może nigdy nie byłbyś w stanie handlować wystarczająco długo, aby zdobyć żadnych klientów.
Po pierwsze, mam nadzieję, że obciążysz swoich klientów wystarczająco, aby pokryć WSZYSTKIE koszty utrzymania ich niestandardowych wersji. Zakładam, że klienci oczekują, że otrzymają nowe wersje bez konieczności płacenia za ponowne dostosowanie. Zacznę od znalezienia wszystkich plików, które są takie same w 95% twoich oddziałów. To 95% to stabilna część twojej aplikacji.
Następnie znajdź wszystkie pliki, które mają tylko kilka linii różniących się między gałęziami - spróbuj wprowadzić system konfiguracji, aby różnice te można było usunąć. Na przykład zamiast 100 plików z różnymi polami tekstowymi, masz 1 plik konfiguracyjny, który może zastąpić dowolną etykietę tekstową. (Nie trzeba tego robić za jednym razem, wystarczy skonfigurować etykietę pola tekstowego za pierwszym razem, gdy klient chce ją zmienić).
Następnie przejdź do trudniejszych problemów przy użyciu wzorca strategii, wstrzyknięcia zależności itp.
Rozważ przechowywanie jsonów w bazie danych zamiast dodawania kolumn do pól własnych klienta - może to działać, jeśli nie musisz przeszukiwać tych pól za pomocą SQL.
Za każdym razem, gdy sprawdzasz plik w gałęzi, MUSISZ różnicować go za pomocą main i uzasadniać każdą zmianę, w tym spację. Wiele zmian nie będzie potrzebnych i można je usunąć przed zameldowaniem. Może to wynikać tylko z tego, że jeden programista ma w swoim edytorze różne ustawienia dotyczące formatowania kodu.
Zamierzasz najpierw przejść od 500 oddziałów z dużą ilością plików, które są różne, do większości oddziałów mających tylko kilka plików, które są różne. Zarabiając wciąż wystarczająco dużo pieniędzy, aby żyć.
Przez wiele lat możesz mieć 500 oddziałów, ale jeśli są one łatwiejsze w zarządzaniu, to wygrałeś.
Na podstawie komentarza br3w5:
Wykonaj powyższe czynności dopiero po zdobyciu łatwego ziarna i prześledź je najpierw kilkoma klasami.
źródło
W przyszłości zadaj pytania testowe Joela w swoim wywiadzie. Bardziej prawdopodobne jest, że nie wejdziesz do wraku pociągu.
To jest, ach, jak to powiedzieć ... naprawdę, naprawdę zły problem. „Stopa procentowa” tego długu technicznego będzie bardzo, bardzo wysoka. To może nie być możliwe do odzyskania ...
Jak zintegrowane z „rdzeniem” są te niestandardowe zmiany? Czy możesz zrobić z nich własną bibliotekę i mieć jeden „rdzeń”, a każdy konkretny klient ma swój „dodatek”?
Czy te wszystkie bardzo małe konfiguracje?
Myślę, że rozwiązaniem jest połączenie:
Żadne nie będzie banalne, jakbyś znalazł się tutaj z ponad 500 klientami, prawdopodobnie nie zrobiłeś w tym żadnego prawdziwego rozróżnienia. Oczekuję, że twoje zmiany w rozdzieleniu tego będą bardzo czasochłonne.
Podejrzewam również, że będziesz miał poważne problemy z łatwym wyodrębnieniem i kategoryzowaniem całego kodu specyficznego dla klienta.
Jeśli większość zmian są szczegółowo różnice brzmieniem Proponuję pytania czytania jak to o lokalizacji językowej. Niezależnie od tego, czy robisz wiele języków w całości, czy tylko w podzbiorze, rozwiązanie jest takie samo. Dotyczy to w szczególności PHP i lokalizacji.
źródło
Jest to jeden z najgorszych anty-wzorów, które można trafić dowolnym VCS.
Prawidłowym podejściem jest tutaj przekształcenie niestandardowego kodu w coś napędzanego przez konfigurację, a następnie każdy klient może mieć własną konfigurację, zapisaną na stałe w pliku konfiguracyjnym lub w bazie danych lub w innej lokalizacji. Możesz włączyć lub wyłączyć całe funkcje, dostosować wygląd odpowiedzi i tak dalej.
Pozwala to zachować jedną gałąź główną z kodem produkcyjnym.
źródło
if(getFeature(FEATURE_X).isEnabled())
cały czas.Celem oddziałów jest zbadanie jednej możliwej ścieżki rozwoju bez ryzyka naruszenia stabilności głównej gałęzi. Powinny one ostatecznie zostać połączone w odpowiednim czasie lub odrzucone, jeśli prowadzą do ślepej uliczki. To, co masz, to nie tyle gałęzi, co raczej 500 widelców tego samego projektu i próba zastosowania wszystkich istotnych zestawów zmian do wszystkich z nich to syzyfowe zadanie.
Zamiast tego powinieneś zamiast tego mieć swój podstawowy kod w swoim własnym repozytorium, z niezbędnymi punktami wejścia do modyfikowania zachowania poprzez konfigurację i wstrzykiwania zachowania, na co pozwalają odwrócone zależności .
Różne konfiguracje, które masz dla klientów, mogą albo po prostu odróżnić się po jakimś zewnętrznie skonfigurowanym stanie (np. Baza danych) lub, jeśli to konieczne, żyć jako osobne repozytoria, które dodają rdzeń jako podmoduł.
źródło
Wszystkie ważne rzeczy zostały tutaj zaproponowane przez dobre odpowiedzi. Chciałbym dodać moje pięć pensów jako sugestię procesu.
Chciałbym zasugerować rozwiązanie tego problemu w długim lub średnim okresie i przyjęcie zasad, w jaki sposób opracowywać kod. Spróbuj zostać elastycznym zespołem do nauki. Jeśli ktoś może mieć 500 repozytoriów zamiast konfigurować oprogramowanie, nadszedł czas, aby zadać sobie pytanie, jak dotychczas pracowałeś i zrobisz to od teraz.
Co znaczy:
W żaden sposób nie ma to na celu stworzenia atmosfery złego ciśnienia w Twoim zespole. Raczej sugeruję, abyś najpierw wyjaśnił sobie te kwestie i, gdziekolwiek poczujesz wsparcie, zorganizuj to razem ze swoim zespołem. Zaproś osoby przyjazne do stołu, aby poprawić swoje wrażenia.
Następnie spróbuj ustanowić długoterminowe okno czasowe, w którym gotujesz to na małym płomieniu. Sugestia: spróbuj scalić co najmniej dwa repozytoria co tydzień, a zatem usuń co najmniej jedno . Możesz się tego często nauczyć, możesz połączyć więcej niż dwie gałęzie, uzyskując rutynę i nadzór. W ten sposób w ciągu jednego roku możesz zająć się najgorszymi (najdroższymi?) Oddziałami, a za dwa lata możesz zmniejszyć ten problem, aby mieć wyraźnie lepsze oprogramowanie. Ale nie oczekuj więcej, ponieważ ostatecznie nikt nie będzie miał na to czasu, ale to Ty nie będziesz już na to pozwalać, ponieważ jesteś architektem oprogramowania.
W ten sposób spróbowałbym sobie z tym poradzić, gdybym był na twojej pozycji. Nie wiem jednak, w jaki sposób Twój zespół zaakceptuje takie rzeczy, w jaki sposób oprogramowanie na to naprawdę pozwala, w jaki sposób otrzymujesz wsparcie, a także czego jeszcze musisz się nauczyć. Jesteś architektem oprogramowania - po prostu idź :-)
źródło
Kontrastując wszystkich nieprzyzwoitych mówców, załóżmy prawdziwą potrzebę biznesową.
(na przykład kodem dostarczanym jest kod źródłowy, klienci pochodzą z tej samej branży, a zatem są ze sobą konkurenci, a model biznesowy obiecuje zachować tajemnicę)
Ponadto załóżmy, że Twoja firma posiada narzędzia do utrzymania wszystkich oddziałów, czyli albo siły roboczej (powiedzmy 100 programistów zaangażowanych w łączenie, zakładając 5-dniowe opóźnienie wydania; lub 10 programistów zakładających, że 50-dniowe opóźnienie wydania jest OK), lub tak niesamowite zautomatyzowane testy, że automatyczne połączenia są naprawdę testowane zarówno pod kątem specyfikacji podstawowej, jak i specyfikacji rozszerzenia w każdej branży, a zatem tylko zmiany, które nie łączą się „czysto”, wymagają interwencji człowieka. Jeśli klienci płacą nie tylko za dostosowania, ale za ich utrzymanie, może to być prawidłowy model biznesowy.
Moje (i nie-mówcy) pytanie brzmi: czy masz dedykowaną osobę odpowiedzialną za dostawę do każdego klienta? Jeśli jesteś, powiedzmy, firmą liczącą 10 000 osób, może tak być.
W niektórych przypadkach może to być obsługiwane przez architekturę wtyczek , powiedzmy, że twoim rdzeniem jest pień, wtyczki mogą być przechowywane w pniu lub gałęziach, a konfiguracja dla każdego klienta jest plikiem o unikalnej nazwie lub jest przechowywana w oddziale klienta.
Wtyczki mogą być ładowane w czasie wykonywania lub wbudowane w czasie kompilacji.
Naprawdę wiele projektów jest wykonywanych w ten sposób, nadal występuje zasadniczo ten sam problem - proste podstawowe zmiany są trywialne w integracji, zmiany konfliktu muszą zostać wycofane lub zmiany w wielu wtyczkach.
Zdarzają się przypadki, gdy wtyczki nie są wystarczająco dobre, wtedy tak wiele wewnętrznych elementów rdzenia musi zostać poprawionych, że liczba interfejsów wtyczek staje się zbyt duża, aby poradzić sobie.
Idealnie byłoby to obsługiwane przez programowanie aspektowe , w którym trunk jest kodem podstawowym, a gałęzie są aspektami (to jest dodatkowy kod i instrukcje, jak podłączyć dodatki do rdzenia)
Prosty przykład, możesz określić, że niestandardowy
foo
jest uruchamiany przed rdzeniem lub poklass.foo
nim, że zastępuje go, lub że otacza go i może zmieniać dane wejściowe lub wyjściowe.Jest na to mnóstwo bibliotek, jednak problem łączenia konfliktów nie ustępuje - czyste połączenia są obsługiwane przez AOP, a konflikty nadal wymagają interwencji człowieka.
Wreszcie, taki biznes naprawdę musi zajmować się utrzymaniem oddziału , a mianowicie, czy funkcja X specyficzna dla klienta jest tak powszechna, że przeniesienie jej do rdzenia jest tańsze, chociaż nie wszyscy klienci płacą za to?
źródło
Nie rozwiązujesz przyczyny choroby, patrząc na objaw. Stosowanie podejścia „zarządzania kodem” jest objawowe, ale nie rozwiąże problemu na dłuższą metę. Główną przyczyną jest brak „dobrze zarządzanych” możliwości produktu, funkcji oraz ich rozszerzeń i odmian.
Twój „niestandardowy” kod reprezentuje jedynie rozszerzenia funkcji i możliwości produktu oraz zmiany pól danych w innych.
Jak szerokie są funkcje niestandardowe, jak różne, jak kontekstowo podobne, czy nie, będą miały duży wpływ na „odkażanie” bazy kodu produktu.
To nie tylko sposób kodowania i wersji - to miejsce, w którym odgrywa rolę zarządzanie produktem, architektura produktu i architektura danych . Poważnie.
Ponieważ pod koniec dnia kod jest niczym innym, jak oferowaniem klientom funkcji biznesowych i produktów / usług . Za to firma otrzymuje wynagrodzenie.
Lepsze zrozumienie tego musi wynikać z punktu widzenia „możliwości”, a nie z punktu widzenia kodu.
Ty, Twoja firma i produkt nie może być wszystkim dla wszystkich. Teraz, gdy masz przyzwoitą bazę przychodów wynoszącą 500 klientów, nadszedł czas, aby wyprodukować to, co zamierzasz być.
A jeśli oferujesz kilka rzeczy, sensowne byłoby zmodularyzowanie możliwości produktu w zorganizowany sposób.
Jak szerokie i głębokie będą twoje produkty? W przeciwnym razie doprowadzi to do problemów związanych z „jakością usług” oraz „rozwodnieniem i rozdrobnieniem produktu”.
Będziesz CRM lub ERP lub kolejność przetwarzania / wysyłki lub Microsoft Excel?
Istniejące rozszerzenia trzeba zakasać i harmonizować, tak duża oprogramowania główne ściąga i łączy produkty nabyte od uruchomienia.
Musisz mieć silną osobę zarządzającą produktem i architekturę danych mapującą następujące elementy:
... aby stworzyć mapę drogową asymilacji i harmonizacji wszystkich tych luźnych wątków / gałęzi produktów w wielkim kontekście swojej podstawowej aplikacji.
PS: Połącz się ze mną, znam osobę, która może pomóc Ci to naprawić :)
źródło
Mogę się z tym odnosić. Podjąłem wiele projektów. W rzeczywistości 90% naszych prac rozwojowych polega na naprawianiu takich rzeczy. Nie każdy jest doskonały, więc sugeruję, abyś używał kontroli wersji we właściwy sposób i gdzie jesteś, jeśli to możliwe, możesz wykonać następujące czynności.
Osobiście zaimportowałem repozytorium z GitHub z 40 oddziałami do Bitbucket i utworzyłem 40 repozytoriów. Zajęło to tylko cztery godziny. To były odmiany motywów WordPress, więc push i pull były szybkie.
Istnieje wiele powodów, dla których „nie robi się dobrze za pierwszym razem” i myślę, że ci, którzy je szybko zaakceptują i przejdą do „zrób to dobrze tym razem”, zawsze będą odnosić sukcesy.
źródło