One NuGet please!

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:

OneNuget_ProjectStructure

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:

  1. Dwoch rozszerzen do TFS’a:

    • TFS Versioning – wymagana do inkrementacji wersji biblioteki po kazdym buildzie
    • TFS NuGetter – wymagana do tworzenia paczki NuGet’a
  2. NuGet Server – wymagany do hostowania paczek i propagowania informacji o nowych paczkach (via RSS)
  3. Windows Management Framework 3.0 – zawierajacy PowerShell’a 3.0 wymaganego przez rozszerzenia powyzej
  4. 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:

OneNuget_CustomActivities

I wskazujemy go TFS Build Controller’owi jako nasz folder z “custom assemblies”.

OneNuget_TFSCustomAssemblies

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:

OneNuget_BuildTemplate

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

OneNuget_NuGetPackageSource

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!


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.