Przepraszam za ten długi post, ale myślę, że warto.
Właśnie zacząłem od małego sklepu .NET, który działa zupełnie inaczej niż w innych miejscach, w których pracowałem. W przeciwieństwie do którejkolwiek z moich poprzednich pozycji, oprogramowanie tutaj napisane jest skierowane do wielu klientów i nie każdy klient otrzymuje jednocześnie najnowszą wersję oprogramowania. W związku z tym nie ma „aktualnej wersji produkcyjnej”. Gdy klient otrzymuje aktualizację, otrzymuje także wszystkie funkcje dodane do oprogramowania od czasu ostatniej aktualizacji, która może być dawno temu. Oprogramowanie jest wysoce konfigurowalne, a funkcje można włączać i wyłączać: tak zwane „przełączanie funkcji”. Cykle wydań są tutaj bardzo napięte, w rzeczywistości nie odbywają się zgodnie z harmonogramem: po zakończeniu funkcji oprogramowanie zostaje wdrożone u odpowiedniego klienta.
Zespół dopiero w zeszłym roku przeniósł się z Visual Source Safe do Team Foundation Server. Problem polega na tym, że nadal używają TFS tak, jakby to był VSS i wymuszają blokady Checkout w pojedynczej gałęzi kodu. Ilekroć pojawia się poprawka błędu w terenie (nawet dla jednego klienta), po prostu budują wszystko, co jest w TFS, testuj błąd został naprawiony i wdrażaj go u klienta! (Sam pochodzący z branży oprogramowania farmaceutycznego i urządzeń medycznych jest to niewiarygodne!). Rezultat jest taki, że w połowie upieczony kod deweloperski zostaje wprowadzony do produkcji nawet bez testowania. Błędy zawsze pojawiają się w kompilacjach wersji, ale często klient, który właśnie otrzymał kompilację, nie zobaczy tych błędów, jeśli nie skorzystają z funkcji, w której jest błąd. Dyrektor wie, że to problem, ponieważ firma zaczyna się rozwijać nagle kilku dużych klientów przybywa na pokład i mniejszych.
Poproszono mnie o przyjrzenie się opcjom kontroli źródła, aby wyeliminować wdrażanie błędnego lub niedokończonego kodu, ale nie poświęcać nieco asynchronicznej natury wydań zespołów. W swojej karierze korzystałem z VSS, TFS, SVN i Bazaar, ale to właśnie tam większość mojego doświadczenia dotyczyła TFS.
Wcześniej większość zespołów, z którymi współpracowałem, używa dwu- lub trzygałęziowego rozwiązania Dev-Test-Prod, gdzie przez miesiąc programiści pracują bezpośrednio w Dev, a następnie zmiany są łączone w Test, a następnie Prod, lub promowane „kiedy to zrobione”, a nie na stały cykl. Zastosowano zautomatyzowane kompilacje, korzystając z tempomatu lub kompilacji zespołu. W mojej poprzedniej pracy bazar był używany na szczycie SVN: deweloperzy pracowali we własnych małych gałęziach funkcji, a następnie wypchnęli swoje zmiany do SVN (powiązanego z TeamCity). Było to miłe, ponieważ łatwo było izolować zmiany i dzielić się nimi z gałęziami innych ludzi.
W obu tych modelach istniała centralna gałąź programisty i prod (a czasem testowa), przez którą przepchnięto kod (a etykiety zostały oznaczone do oznaczenia kompilacji w prod, z których zostały wydane wydania ... i zostały one przekształcone w gałęzie dla poprawek błędów do wydań i połączyło się z powrotem w dev). Jednak tak naprawdę nie pasuje to do sposobu pracy: nie ma kolejności, kiedy różne funkcje zostaną wydane, zostaną one wypchnięte, gdy są kompletne.
W przypadku tego wymogu podejście polegające na „ciągłej integracji”, jak widzę, się załamuje. Aby wydobyć nową funkcję z ciągłą integracją, należy ją wypchnąć za pośrednictwem narzędzia deweloperskiego, które uchwyci wszelkie niedokończone prace w deweloperach.
Myślę, że aby temu zaradzić, powinniśmy przejść do mocno rozgałęzionego modelu bez ŻADNYCH gałęzi deweloperów, raczej źródło powinno istnieć jako seria gałęzi cech, które po zakończeniu prac programistycznych są zablokowane, przetestowane, naprawione, zablokowane , przetestowane, a następnie wydane. Inne gałęzie cech mogą pobierać zmiany z innych gałęzi, kiedy ich potrzebują / chcą, więc ostatecznie wszystkie zmiany zostaną wchłonięte przez wszystkich innych. To bardzo pasuje do czystego modelu Bazar z tego, czego doświadczyłem podczas mojej ostatniej pracy.
Choć brzmi to elastycznie, wydaje się dziwne, że nie ma gdzieś gałęzi dewelopera lub prowokatora, i martwię się o gałęzie, które nie chcą się ponownie zintegrować, lub że dokonano drobnych późnych zmian, które nigdy nie zostaną przeniesione do innych gałęzi i deweloperzy narzekają na scal katastrofy ...
Co o tym myślą ludzie?
Drugie ostatnie pytanie: jestem nieco zdezorientowany co do dokładnej definicji rozproszonej kontroli źródła: niektórzy zdają się sugerować, że chodzi tu tylko o brak centralnego repozytorium, takiego jak TFS lub SVN, niektórzy twierdzą, że chodzi o odłączenie (SVN jest odłączony w 90% a TFS ma doskonale funkcjonalny tryb offline), a inni twierdzą, że chodzi o rozgałęzianie funkcji i łatwość łączenia oddziałów bez relacji rodzic-dziecko (TFS ma również bezpodstawne scalanie!). Być może jest to drugie pytanie!
Odpowiedzi:
Co definiuje DVCS?
Te rozproszone w DVCS oznacza, że każdy klon repozytorium zawiera wszystkie informacje wymagane w celu popełnienia, aktualizacji, gałąź, scalenia lub poszukać wszelkich zmianach w tym repozytorium, bez dotykania serwera . Jedyną rzeczą, którą możesz zrobić w trybie offline,
svn
jest edycja plików - potrzebujesz dostępu do serwera dla prawie wszystkichsvn
poleceń, w tym robienia czegoś tak prostego jak grepowaniesvn log
, więc w rzeczywistości jest on bliższy 0% niż 90%!Wszelkie autorytatywne centralne repozytorium, które możesz skonfigurować w przepływie pracy DVCS, to po prostu kolejny klon , a jedyny czas, z którym musisz się z nim komunikować, to usunięcie aktualizacji innych osób lub wprowadzenie własnych zmian, aby inni mogli je zobaczyć , prawie wszystko inne można zrobić offline.
Jaki model rozgałęziania jest odpowiedni?
Byłem w sytuacji, w której jesteś teraz. Takie systemy mogą być prawdziwym bólem, ale musisz zrozumieć pragmatyczne powody, dla których tak się stało i zdać sobie sprawę, że nie są już poza odkupieniem . Opracowano wiele narzędzi, które mogą pomóc w zarządzaniu tego rodzaju złożonością .
Po pierwsze, bez względu na to, co robisz, nie pokazuj ludziom udanego modelu rozgałęziania git , po prostu ich pomieszasz i wyłączy. Zamiast tego opracuj własny model, który odzwierciedla istniejący przepływ pracy , ale rozwiązuje problemy z istniejącym przepływem pracy .
Niektóre zasoby, które warto rozważyć, to między innymi podmoduły git, które pozwolą różnym wersjom klientów na określenie różnych kombinacji konfiguracji klienta, modułów aplikacji i bibliotek. Inną opcją byłoby zastosowanie systemu zarządzania poprawkami do stosowania kolejek poprawek specyficznych dla klienta / produktu.
Obie te opcje zapewnią znacznie większą elastyczność, przejrzystość i bezpieczeństwo niż obecny przepływ pracy i mogą być łatwiejsze w użyciu niż nawet bardziej złożona strategia tylko dla gałęzi. Z pewnością żałuję, że nie mam dostępu do tych narzędzi, kiedy byłem w twojej sytuacji.
Aby uzyskać więcej informacji na temat tych opcji, zobacz moje odpowiedzi do strategii użyć kontroli wersji w systemie modułowym , jak korzystać z repozytorium Subversion Wewnątrz Git repozytorium? oraz Kontrola źródła / wersji aplikacji używanej przez wiele firm .
Ostatecznie jest to naprawdę coś, co będziesz musiał opracować z resztą zespołu. Jeśli masz wizję zaproponowania czegoś, co działa lepiej niż to, co już masz, i możesz uzyskać wpis od innych programistów, będziesz miał o wiele łatwiej.
Najważniejszą rzeczą jest pokazanie kolegom, w jaki sposób to, co zaproponujesz, ułatwi ich życie . Gdy zostaną przekonani, masz znacznie większą szansę na to, aby kierownictwo pozbyło się inwestycji w TFS i zaczęło korzystać z modelu bardziej odpowiedniego do twoich metod pracy.
źródło
Po pierwsze, DVCS jest zapowiedzią problemów, które masz - używane narzędzie kontroli wersji nie jest źródłem problemów, które należy rozwiązać. Możliwe, że istnieją aspekty rozwiązań DVCS, które są „lepsze” niż TFS, ale nie jest to, co należy w tym momencie naprawić.
Zidentyfikowałeś, że potrzebujesz funkcjonalnej struktury rozgałęziania, która pasuje do Twojej organizacji - myślę, że nadal będziesz mieć połączenie dalekosiężne, gdy funkcja jest ukończona, z powrotem łączy się z bagażnikiem i zostaje zamknięta. Jest kilka fajnych przemyśleń na temat tego, jak wdrażasz typowe zależności.
Musisz także zapewnić ciągłą integrację działającą (nie ma powodu, aby nie mieć automatycznej kompilacji dla każdej aktywnej gałęzi, abyś miał pewność, że możesz zbudować tę gałąź i że przejdzie ona odpowiednie testy). Czuję się niekomfortowo, gdy zatwierdzenie (a przynajmniej „push”) nie uruchamia dla mnie kompilacji.
I musisz zacząć od automatycznych testów na wszystkich poziomach, a zwłaszcza testów jednostkowych i testów integracyjnych, aby zacząć zmniejszać szanse na ucieczkę nowych błędów w środowisku naturalnym. To ostatnie jest ogromne i coś, z czym wciąż się zmagam, ale jasne jest, że kiedy już będziesz wiedział, że możesz budować, będzie to miało największą wartość.
Musisz to połączyć z upewnieniem się, że Twoje pakiety wdrożeniowe pochodzą z kompilacji serwera, a wdrożenie jest zautomatyzowane w miarę możliwości (przejście od artefaktu kompilacji serwera do kodu wdrożonego na żywo przy minimalnym wysiłku i minimalnym obciążeniu).
Hmm, założyłem, że istnieje ładna, dobrze uporządkowana konfiguracja śledzenia problemów ... też tego potrzebujesz i aby mieć pewność, że jest używana poprawnie. Idealnie byłoby, gdyby aplikacje działające na żywo automatycznie przekazywały błędy do tego systemu (lub w celu segregacji).
Na koniec nie próbuj rozwiązywać wszystkich problemów naraz - wydaje mi się, że kompilacja i test to miejsca, na które powinieneś się skupić.
źródło
Drugie pytanie jest łatwiejsze i krótsze, więc spróbuję zacząć od niego
DVCS to system, w którym nie ma jednego „autorytatywnego” źródła kodu (oprócz „na podstawie umowy”, jeśli jest używane), a wymiana danych P2P jest możliwa bez dodatkowych poziomów (osobista, niekanoniczna definicja)
Na temat pierwszego pytania
Obawiam się, że firma musi zrekonstruować przepływ pracy i przemyśleć styl, aby uzyskać „jakoś zarządzany i przewidywalny kod”. Nie mogę powiedzieć o TFS (z wyjątkiem osobistej opinii i poczucia, że jest to słaby system w części Kontrola wersji / bezpodstawne scalanie jest złe /), ale dla dowolnego VCS w twojej sytuacji („Produkt” jest zbiorem niezależnych „modułów”, każdy „Klient” otrzymuje inne „Produkty” - czy to założenie jest prawidłowe?) Wolę podział rozwoju modułów na osobne gałęzie, mam Produkt jako „Supermoduł” (także gałąź?), tam każdy moduł jest powiązany z konkretną wersją modułu- gałąź, moduł rozwoju używa paradygmatu gałąź-zadanie (a gałąź-moduł składa się tylko z zestawów scalających).
W ten sposób zawsze możesz wiedzieć, która „Kolekcja” (tj. Zestaw modułów i odpowiadające im wersje) tworzą każdy „Produkt”, ma możliwość wykonania CI (dla gotowych i połączonych gałęzi zadań), testowania jednostek i kompilacji
źródło
Główne pytanie dotyczące reklamy: Uważam, że to, o czym mówisz, jest dokładnie tym, o co chodzi w udanym modelu rozgałęzienia git (i przepływie git pomocnika do obsługi go). Posiadaj gałąź główną, która jest zawsze w stanie do wdrożenia i wykonuj całą pracę na gałęziach funkcji.
Możesz także użyć procesu używanego przez sam git, który wywodzi się z tej samej podstawowej zasady. W rozwoju git-core cała praca odbywa się w gałęziach funkcji. Gałęzie funkcji są przesyłane do integratora, który uruchamia skrypt, aby połączyć je wszystkie w celu utworzenia gałęzi o nazwie
pu
(proponowane aktualizacje). Różni ludzie biorą tę gałąź i pracują z nią, aby ją przetestować.Zamiast integratora możesz mieć serwer ciągłej integracji, który wykonuje to scalanie na początku kompilacji. W ten sposób za każdym razem, gdy ktokolwiek z zespołu przesyła zmiany do centralnego repozytorium jako gałęzi funkcji (prawdopodobnie używając jakiejś konwencji nazewnictwa, aby powiedzieć, które gałęzie należy wybrać).
W git oddział cecha niż przystąpi do
next
,master
lubmaint
w zależności od zwolnić to ukierunkowanie na (maint jest bugfixing aktualnego wydania, mistrzowskie dla bieżącej wersji i dalej z jednym następnie w-przygotowaniu), ale nie trzeba, że wiele.Podczas gdy funkcje są włączone
pu
(„gotowanie” w terminologii opiekuna git), są one przewijane, apu
gałąź jest odrzucana i tworzona za każdym razem, co ułatwia przeglądanie, ale nie nadaje się do oparcia na innych pracach. Kiedy gałąź funkcji jest scalona w jedną z głównych linii, jest zamykana na przewijanie do tyłu, a kolejne poprawki są wprowadzane jako nowe zatwierdzenia.Osobiście polecam
git
najlepiej. Początkowo jest nieco trudniej się uczyć, ponieważ rośnie bardziej organicznie, ale ostatecznie wydaje się najbardziej elastyczny. Ale każdy z trzech systemów rozproszonych, git, mercurial i bazar, będzie ci dobrze służył (i często możesz je nawet mieszać, np. Mercurial może ciągnąć i wypychać do / z repozytorium git i, moim zdaniem, może bazar).Drugie pytanie: nauczono mnie, że „rozproszony” ogólnie oznacza, że możesz przenosić obiekty i zachowują swoją tożsamość. To właśnie robi rozproszona kontrola wersji: klonujesz repozytorium, które zawiera te same zatwierdzenia i pozwala robić z nimi te same rzeczy. Łatwość rozgałęziania i odłączania operacji są głównymi funkcjami na poziomie użytkownika, które wynikają z zasady przenoszenia zatwierdzeń i ukierunkowanego układu graficznego, który pozwala na to.
źródło
Niestety nie ma znanego rozwiązania błędów w kodzie :)
Chcesz po prostu powstrzymać niedokończone kontrole przed uwikłaniem się w główne wydanie, a jedyną odpowiedzią na to jest łączenie gałęzi dla każdego programisty. Zrobiłem to w poprzedniej firmie przy użyciu Clearcase, działało całkiem dobrze (chociaż musieliśmy mieć kilkunastu administratorów Clearcase).
Teraz zakładam również, że naprawiasz błędy w wersji produktu, którą ma obecnie każdy klient ... więc masz problem ze scaleniem, przenosząc poprawki z wersji A do wersji Z. Nie ma łatwego sposobu, aby sobie z tym poradzić to, ale będziesz musiał mieć oddział dla każdej wysyłanej wersji. Najlepszym sposobem na poradzenie sobie z tym jest utrzymywanie gałęzi funkcji tylko w najnowszej wersji i zachęcanie klientów do aktualizacji, aby uzyskać nowe funkcje, jednocześnie naprawiając błędy bezpośrednio w gałęzi wydania i łącząc je w górę ze wszystkimi innymi gałęziami wydania po zakończeniu.
Niezbyt fajnie, ale może zadziałać wyjątkowo dobrze. Trzymasz kod uporządkowany i ładnie oddzielny. Jest również łatwy do zrozumienia dla innych deweloperów - małe poprawki błędów bezpośrednio w „kodzie”, wszystko więcej niż kilka wierszy jest wykonywanych w dedykowanym oddziale, gdzie mogą zająć tyle czasu, ile chcą. (będziesz musiał rozwiązać problemy ze scalaniem i zapewnić ich, że jest w porządku, jeśli 2 programistów pracuje nad 2 funkcjami jednocześnie !!)
Po pewnym czasie możesz również wprowadzić gałęzie funkcji w gałęziach wydania, w których błędy są naprawiane, a następnie łączone, ale IMHO zazwyczaj wymaga więcej wysiłku, niż potrzeba. Jeśli jednak chcesz dodać funkcje do starych wydań, musisz postępować zgodnie z tym podejściem - rozgałęzić gałąź wydania, a następnie scalić kod z powrotem do tego wydania i scalić zmianę w górę do późniejszych wydań. To sprawi, że Twój zespół testowy będzie bardzo niezadowolony, ponieważ wydania będą znacznie opóźnione z powodu konieczności wielokrotnego testowania kilku wersji, a zespół deweloperów będzie niezadowolony, ponieważ będą musieli wykonać wiele scaleń, zanim będą mogli zacząć od nowego kodu (w mojej obecnej firmie dzieje się tak, głównie ze względu na ilość pracy, którą zawsze musimy wykonać jak najszybciej).
DVCS:
w zasadzie DVCS to miejsce, w którym każdy ma własną kopię repozytorium serwera. Ma pewne zalety (szczególnie w rozproszonych zespołach z ograniczoną komunikacją), ale ma też pewne wady, więc sprawdź je przed przejściem na DVCS. Jeśli jesteś sklepem z systemem Windows, prawdopodobnie przekonasz się, że Mercurial jest najlepszym DVCS dla Ciebie.
źródło