“Gdybym wiedzial, ze tak bedzie, to bym tak nie zrobil“… czasem mozna powtarzac to jak mantre. Ktos kiedys, podejmuje jakas decyzje, ktora w danym momencie wydaje sie byc dobra (lub jest niedokonca przemyslana :)), decyzje ktora rozwiazuje pewien problem i dziala… dopoki nie pojawi sie inny, nowy 😉 wtedy podejmujemy nowa decyzje, ktora rozwiazuje stary problem, ten nowy i inny..potencjalny (jesli poswiecilismy chwile czasu na zastanowienie sie nad takim). I wszystko dziala… rzecz jasna… do momentu az nie pojawi sie kolejny problem X :). Dzis o jednej z takich decyzji podjetych w odpowiedzi na problem X…
Ale od poczatku… byla sobie struktura projektow, w ktorej ktos kiedys umiescil na samej gorze folder “lib” (zawierajcy wszystkie potrzebne dll’ki), z domyslem by wszystkie dll’ki byly w jednym miejscu, a projekty nizej z nich korzystaly. W duzym uproszczeniu wygladalo to mniej wiecej tak:
Z biegiem czasu powstaly nowe projekty, pojawily sie nowe branch’e i doszly automatyczne buildy. Wiecej projektow = wiecej problemow..
Za kazdym razem gdy byl tworzony nowy branch, cale drzewko projektow bylo tez powielane, a to bo projekty nizej tworzyly “jedna wspolna paczke”, a to by utrzymac referencje do dll’ek.
Mialo byc czysto i przyjemnie, zrobilo sie niemilo. Jeszcze mniej mile zrobilo sie gdy doszedl build “Continous Integration” oparty o TFS’a – zaczela sie bowiem zabawa z serii “co ma byc widzialne, a co niewidzialne dla builda”.
Z racji tego ze bibilioteki byly ulokowane tak wysoko, a projekt tak nisko, TfsBuild musial widziec cala drzewko. Z racji ze mial reagowac na zmiany w “Projekcie 1”, nie mogl widziec zmian wbijanych dla pozostalych projektow. Im wiecej projektow zlokalizowanych ponizej, tym przy kazdej definicji trzeba zdefiniowac, co ma byc widzialne, a co niewidzialne – fun like hell… ;|
Z czasem, ktos zmienia jedna dll’ke na inna, Projekt X dziala sobie dalej… niestety Projekt Y i Z juz nie, bo dll’ka miala byc “o taka”, a jest “o taka”.
Wiadomo, problemy, problemy, problemy…. a gdyby tak.. pozbyc sie lib’a i trzymac wszystko co nam potrzebne na poziomie projektu. Wtedy wilk bylby syty.. a i owca cala. Tylko jakby to zrobic, by pracujac w jednym projekcie, moc wiedziec o tym ze pojawil sie jakis update do dll’ki XYZ? .. I tu zrodzil sie pomysl… a gdyby tak napchac wilka owczymi NuGet’ami? 🙂
Czym NuGet jest, wydaje mi sie ze w dzisiejszych czasach nie musze nikomu tlumaczyc 😉
W efekcie malych zmian, projekty korzystaja z NuGet’owych paczek. Biblioteki lokalne, rowniez sa dystrybuowane za pomoca lokalnego NuGet serwera.
Kazda zmiana w bibliotece, budowana jest przez lokalny Build Server – jesli przejdzie pomyslnie wszystkie unit testy – tworzona jest nowa paczuszka i informacja o niej propagowana jest przez lokalny NuGet server.
W efekcie, dostajemy tylko to co potrzebujemy, nie trzeba sie bawic wiecej w co nasz build winien widziec, a czego nie. Latwiej tworzyc jest nowy branch. Zmiana wersji bilioteki nie wymusza update’u we wszystkich pozostalych projektach – mozna uzywac to co sie chce, w wersji takiej jakiej sie chce.
Do realizacji takiego podejscia mozna uzyc:
-
Dwoch rozszerzen do TFS’a:
- TFS Versioning – wymagana do inkrementacji wersji biblioteki po kazdym buildzie
- TFS NuGetter – wymagana do tworzenia paczki NuGet’a
- NuGet Server – wymagany do hostowania paczek i propagowania informacji o nowych paczkach (via RSS)
- Windows Management Framework 3.0 – zawierajacy PowerShell’a 3.0 wymaganego przez rozszerzenia powyzej
- NuGet Package Explorer – przydatny do utworzenia specyfikacji (nuspec) naszego NuGet’a – IMHO latwiej jest sobie to wizualnie wyklikac
Rozszerzenia, wrzucamy do folderka z wszystkimi roszerzeniami w TFS’ie:
I wskazujemy go TFS Build Controller’owi jako nasz folder z “custom assemblies”.
Build templaty, wrzucamy do folderka, w ktorym trzymamy wszystkie pozostale definicje buildow. Na chwile obecna, bawimy sie domyslnym – “NuGetterMultiPkgBuildVersionedTemplate20.xaml”.
Co i jak ustawic, jest bardzo dobrze opisane w dokumentach na Codeplex’ie. Ponizej kilka moich notatek, odnosnie template’u:
A) Build number format: – Revision number resetuje sie za kazdym razem, gdy czesc oprocz &{Rev:r} zmienia sie – czyli jezeli zmieni sie data, numer kolejnego dnia wystartuje od 0. Naturalnie, jak tworzymy paczke, i ma ona wersje 1.0.0.B (gdzie B oznacza numerek kolejnego builda) – to przy normalnym ustawieniu, przy pierwszym buildzie jutro, stworzymy paczke o takim samym numerze jak dzis. Dlatego, lepiej jest zamienic czesc z data, na statyczna czesc, ktora kazdego dnia bedzie taka sama – przez co zawsze bedziemy generowac nowa wersje.
B) Adres do NuGet.exe – podobno mozna uzyc sciezki wzglednej – u mnie nie chcialo dzialac, i dopiero bezwzgledny adres (na build serwerze) zadzialal.
C) Adres do specyfikacji NuGet’a – u mnie specyfikacja byla w folderze NuGet wbita w projekcie – sciezka wzgledna od folderu “Source” (tworzonym podczas build’a) do nuspec’a.
D) Pattern wersji NuGet’a – u mnie 1.0.0.B (gdzie B oznacza kolejnego builda)
E) Lokalizacja folderu “Package” dla NuGet Servera na IIS
F) Informacja o tym czy chcemy wrzucac paczke na koniec builda pod okreslona lokalizacje – jezeli bedzie na “false”, wtedy build bedzie “partially succeed”. Niestety, nie mozna tego parameteru ustawic “On Demand” przy “Queue New Build…” – pozostaje albo miec dwie definicje, albo zawsze wypychac paczuszke.
Po ustawieniu NuGet Servera, mozemy dodac nasz nowy feed w Visual Studio poprzez:
Tools -> Options -> NuGet Package Manager -> Package Source
Na koniec, ciutke o malych niedociagnieciach, tudziez tym, czego mi brak:
– informacja publikowana via RSS jest zbyt skapa – cokolwiek nie ustawie w nuspec’u – dostaje tylko info o tytule paczki (chyba ze to kwestia RSS’a w Outlooku). Idealnie byloby miec info w paczce, z komentarzy do wbitki co sie zmienilo – tudziez jakis changelog.
– brak wizualnej notyfikacji o tym ze jest dostepna nowa paczka (a’la dymek o nowym roszerzeniu dla Visual Studio) – szukalem, nie znalazlem, chyba bedzie trzeba sprobowac wynalezc -.-
I to by bylo na tyle… na obecna chwile.. rozwiazanie sie sprawdza.. czekam na nowy problem X, tudziez krytyke 🙂
Howgh!