Po rozbiciu naszego kodu na bity wielokrotnego użytku, w jaki sposób testujemy i wdrażamy?

9

Zaczęliśmy od jednego programisty i jednego repozytorium svn zawierającego cały nasz kod:

^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1

(w tym czasie była to duża poprawa). Po tym, jak mieliśmy szansę się nieco rozwinąć, zaczęliśmy mieć problemy z zależnościami cyklicznymi, powolnymi testami i ogólnymi trudnościami w ponownym korzystaniu z kodu (ponieważ np. Zestaw funkcji witryny1 wkradł się w inny ogólny moduł a).

Chcąc zmodularyzować bazę kodu i oczekując, że wkrótce przejdziemy do git (i przeczytaliśmy gdzieś, że git nie lubi svn mega-repos), przeszliśmy do bardziej szczegółowej struktury:

^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)

To było świetne pod względem koncepcyjnym. Bardziej modułowy kod, znacznie szybsze pakiety testowe, łatwiejsze do dokumentowania itp. Udostępniliśmy niektóre z naszych bardziej ogólnych komponentów i udostępniliśmy wszystkie moduły do ​​instalacji pip (za pomocą pip install -e .ich instalacji w developmentvirtualenv).

Utworzyliśmy ^/srv/trunkrepozytorium zawierające strukturę folderów środowiska wykonawczego, tj. ^/srv/trunk/libdla modułów, /srv/trunk/srcpozostałości ^/foo/trunk, ^/srv/trunk/wwwstron internetowych itp.

I wreszcie (biorąc pod uwagę pomysł z perforce, z którym pracowałem bardzo dawno temu [ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html] ) stworzyliśmy „vcs- fetch ”plik tekstowy, w którym wymieniono wszystkie stosowne repozytorium i gdzie należy je wypisać do środowiska programistycznego, oraz odpowiednie polecenie, aby to zrobić. Np. Linia vcs-fetc:

svn srv/lib/module-a ^/module-a/trunk

spowodowałoby albo (pierwszy raz)

cd /srv/lib && svn co ^/module-a/trunk module-a

lub (później)

cd /srv/lib/module-a && svn up

i podobnie w przypadku repozytoriów github (zarówno naszych własnych, jak i zmienionych / niezmienionych pakietów dostawców).

Użyliśmy tego samego procesu vcs-fetch do stworzenia środowiska produkcyjnego, ale szybko dowiadujemy się, że nie mamy możliwości dowiedzieć się, która wersja działała w prod po wykonaniu vcs-fetch.

Dzięki mega-repo mogliśmy po prostu zanotować numer wersji przed zaktualizowaniem produ z pnia, a powrót był prosty svn -r nnn up .. Z kodem zarówno w svn, jak i git (i jednym module w hg) - i ~ 120 repos, nie jest oczywiste, jak to zrobić ..

Dzisiaj czytam http://12factor.net/ , a pierwszym czynnikiem jest „One codebase”, więc zastanawiam się też, czy nie jestem tutaj na dobrej drodze?

Jednym z moich pomysłów było stworzenie skryptu wdrażania, który utworzyłby koła „wdrażania” do zainstalowania przez pip i „spakował” je razem w requirements.txtpliku. Wdrożenie obejmowałoby następnie utworzenie nowego pliku virtualenv, instalację pliku pip wymagań.txt z listą kół wdrażania i przełączenie aktywnego pliku virtualenv. Powrót do poprzedniego wymagałby po prostu przełączenia virtualenv z powrotem (ale chyba, że ​​chcieliśmy zachować virtualenvs na zawsze, nie pozwoliłoby nam to wrócić do dowolnego punktu w czasie - z mojego doświadczenia, które nigdy nie było potrzebne).

W tym momencie zastanawiam się, czy idę w złym kierunku, czy po prostu nie poszedłem wystarczająco daleko właściwą ścieżką ...? (wszystko, co czytam, mówi o „Twojej aplikacji” i nie wiem, jak to przekłada się na uruchamianie 14 stron internetowych z tej samej bazy kodu ...)

thebjorn
źródło
Czy mogę założyć, że poszczególne elementy są teraz opracowywane przez różne zespoły o różnych cyklach rozwojowych? Jeśli tak, rozbicie repozytorium jest niemożliwe. Mimo że w git umieszczasz zsynchronizowane tagi wydania dla dużych, stabilnych konfiguracji. Zobacz narzędzie Google repo. Próba dopasowania wersji programistycznych przez zintegrowane metadane jest dość daremna. Łączenie aplikacji za pomocą pip jest również całkowicie uzasadnione.
Ext3h
Jeśli podasz szacunkowe wartości KLOC (1000 wierszy kodu) i miary bajtów kodu, możemy łatwo uzyskać wyobrażenie o wielkości, na przykład „2000 wierszy kodu. 50 kilobajtów kodu źródłowego”. lub „40 KLOC, 2 GB XML”. . Wydaje się, że potrzebujesz tylko migracji do git, a git ma funkcje importowania. Możesz zacząć od przeczytania książki git .
Niklas
1
@ Programmer400 podstawa kodu to: .py 670 kloc, .js: 135kloc, .less: 25kloc, .html: 130kloc. Tak duże, ale nie ogromne. Z tego, co przeczytałem, git tak naprawdę nie lubi repozytoriów tego rozmiaru, więc wyobrażam sobie, że będziemy musieli podzielić się na mniejsze repo przed przejściem na git ..?
thebjorn 26.04.16

Odpowiedzi:

2

Wygląda na to, że brakuje Ci gałęzi (a raczej gałęzi „tagów” ​​lub „release”).

Zamiast używać odwołania SVN jako odniesienia do określenia, którą wersję instalujesz, powinieneś utworzyć gałąź w tej wydanej wersji. Następnie wdróż tę nazwę oddziału.

Ułatwia to rozgałęzienie, nawet jeśli nie ma zmian, więc każdy moduł zachowuje ten sam numer wydania, jednak twoje pakiety OSS mogą nie lubić rozgałęzienia bez zmian, więc następną najlepszą rzeczą jest utrzymanie skryptu zależności - więc wersja 5 produktu wymaga modułu OSS X v2 i tak dalej.

Zmieniłbyś skrypt, by przestał odwoływać się do wersji i zamiast tego pracowałeś z nazwami gałęzi (chociaż mogą to być dowolne, najlepiej wybrać stałą konwencję nazewnictwa, np. Release_1_2_3)

Inną wskazówką jest utrzymywanie pliku z każdym modułem opisującym aktualną wersję, możesz je automatycznie wygenerować, jeśli to konieczne, i być może zawierać również pełny dziennik zmian, ale oznacza to, że każdy może zobaczyć, która wersja jest wdrażana, po prostu patrząc.

gbjbaanb
źródło
1

Myślę, że masz już wiele dobrych pomysłów, większość z nich wykorzystałem w różnych projektach przez lata, a twoim głównym zmartwieniem wydaje się być niezdolność do powiedzenia, która wersja wszystkich modułów jest zawarta w danym pakiecie, jeśli podzielisz się je w górze.

Jestem za ich podzieleniem, na pewnym poziomie szczegółowości, szczególnie jeśli masz wiele zespołów i różne cykle wydawania, jak wspomina @ Ext3h.

Ponieważ nie jestem pewien, jak izolowane są twoje moduły ani jak szczegółowe ma być twoje wersjonowanie, zasugeruję kilka opcji.


Użyj podmodułów git. Za pomocą submodułów możesz przechowywać każdy moduł w osobnym repozytorium git, podobnie do konfiguracji svn, a także do tego, o czym myślisz. Następnie łączysz te moduły z projektem głównym, który będzie zawierał odniesienie do odpowiedniego zatwierdzenia każdego podmodułu, dla każdego jego własnego zatwierdzenia.

IMO to teoretycznie niezła konfiguracja i dość prosta. Główną wadą jest to, że przepływ pracy dla podmodułów jest nieco niewygodny, jednak wydaje się, że wcześniej dobrze rozwiązałeś takie problemy ze skryptami, więc może to nie być prawdziwy problem.

Drugim zastrzeżeniem jest to, że referencje zatwierdzania podmodułu będą po prostu SHA1, nigdy nie ma żadnych czytelnych dla człowieka szczegółów na temat tego, jaką gałęzią jesteś, i może się okazać, że będziesz musiał ręcznie sprawdzić odpowiednią gałąź, jeśli chcesz pracować bezpośrednio w podmodule.

Jednak nie użyłem tego wzorca zbyt często, więc nie wiem, jak duży problem może to być w przypadku dużego projektu, takiego jak twój.


Inną alternatywą jest użycie jakiegoś menedżera zależności. Wymaga to, że każdy moduł lub zestaw modułów może być wersjonowany, pakowany i publikowany osobno, oraz że masz system, który może łączyć te pakiety w pożądany sposób, kiedy chcesz.

Sugerujesz już pip, a tym, co wydaje się brakować w Twojej sugestii, jest przechowywanie wynikowych wymagań. Txt wraz z kompilacją lub w repozytorium projektu root, abyś mógł później ponownie utworzyć virtualenv zamiast zapisywać na dysku.

Istnieją również inne systemy; Skonfigurowałem dość duży projekt, używając nieco spersonalizowanej wersji Apache Ivy jako narzędzia do pakowania i publikowania każdego modułu, a także łączenia ich w końcowy projekt. Ivy przechowuje również manifest z listą wszystkich wersji wszystkich modułów, do których się odwołujesz, jeśli chcesz później odtworzyć konfigurację.

axl
źródło