fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
HOT / 6 minut

Cake – jak wdrażać, aby się nie zrażać


25.11.2019

Aby uruchomić aplikację, zdarza się, że musimy – poza jednorazowym dostosowaniem środowiska programistycznego – za każdym razem wykonywać kilka czynności. Przykładowo: żeby zbudować aplikację typu SPA i zarazem uruchomić API, trzeba przeprowadzić minimum dwie operacje, czyli wystawić API oraz stworzyć pakiet widoków.

Dla jednej aplikacji strata czasu jest „mało” zauważalna, ale co w wypadku, gdy potrzeba postawić 9 systemów i dla każdego wystawić widoki? A co dla 60? Dla masochistów – sytuacja idealna, ale dla osoby, która chce być efektywna w swojej pracy, to strata czasu i nerwów.

Pierwsze, co przychodzi na myśl, to skrypty. Zgoda, pójdziemy jednak dalej.

A co, gdybyśmy wykorzystali coś na wzór PowerShell, ale w kodzie zarządzanym, który potrafi zintegrować ze sobą ponad 50 rozwiązań, od skryptów przez narzędzia aż po usługi? Czemu nie!

Cake

Cake (C# Make) – jak wskazuje nazwa – został oparty na C#.  W jednym narzędziu łączymy moc skryptów, wieloplatformowość oraz zalety kodu zarządzanego. Domyślnym plikiem jest build.cake, w którym definiujemy zadania, a build.ps1 – skryptem, który go uruchamia. Tenże skrypt, zanim uruchomi Cake’a, ściąga potrzebne zależności. Razem z rozwiązaniem tworzy się folder tools, w którym znajdziemy:

  • nuget.exe – aktualny plik uruchamiający NuGet;
  • packages.config – dodatkowe rozszerzenia, z których Cake może korzystać.

Dodatkowo w obrębie tego folderu będą instalowane rozszerzenia oraz dodatki, które można zignorować w systemie kontroli wersji.

MSBuild

W artykule Wyciśnij z MSBuilda ostatnie soki  opisałem, co znaczą poszczególne argumenty. Najważniejsze z nich:

  • UseToolVersion(MSBuildToolVersion.VS2019)– użyj silnika MSBuild z VS2019, czyli v16.
  • WithConsoleLoggerParameter("ErrorsOnly") – wyświetlaj tylko błędy.
  • SetMaxCpuCount(0) – użyj wszystkich rdzeni do budowania.
  • SetNodeReuse(true) – pozwól innym projektom użyć tego samego procesu do budowania.
  • WithProperty("BuildInParallel", "true") – każdy projekt powinien być budowany równolegle (o ile to możliwe).
  • WithProperty("CreateHardLinksFor*", "true") – współdzielone pliki przenieś do RAM i z niego wykonuj zapis/odczyt.

NuGet

Proces ściągania paczek w podstawowej wersji wygląda tak:

Gdy podamy nazwę solucji, rozwiązanie przeszukuje foldery w formacie solucja/solucja.sln.

Proces komplikuje się w momencie uruchomienia tego samego rozwiązania dla kilku solucji naraz. NuGet działa równolegle dla jednego procesu, jednak kiedy odpalimy kilka/kilkanaście takich procesów, to zaczyna się sajgon.

Poza wieloma połączeniami, które obciążają i obniżają szybkość ściągania, NuGet sam w sobie jest chciwy: gdy przynajmniej dwa procesy zechcą skorzystać z tej samej paczki, to wygra pierwszy, a spowodowane jest to pomieszaniem odczytu z zapisem paczek. Wtedy wszystkie procesy się zatrzymają.

Rozwiązaniem jest agregacja projektów do tymczasowej solucji, dla których mają być ściągnięte paczki. Jedno połączenie, brak duplikatów przy ściąganiu, brak walki o paczki, czyli szybki i deterministyczny mechanizm.

NuGet sam w sobie wie, jak się skalować, i jedyne, co będzie nas ograniczało, to szybkość łącza.
Metoda CreateTempSolution do tworzenie solucji jest niczym innym jak sklejeniem ścieżek i GUID-ów do odczytania przez dowolny program wspierający rozszerzenie .sln.

Uruchamianie za pomocą skryptów

Gdy mam już zadania, to czas je uruchomić. Zadania można grupować, aby zachować odpowiednią kolejności, więc dla jednej solucji będzie tak:

dla wielu:

Integracja z innymi usługami oraz narzędziami

Weźmiemy na tapet skrypty PowerShell oraz integracje IIS z ASP.NET oraz ASP.NET Core.

Zadanie trywialne? Może tak, jeśli mówimy o postawieniu jednej aplikacji. Gdy wchodzą różne środowiska (development, UAT, hotfix), a liczba aplikacji się rozrasta, to ręczne stawianie środowiska i przełączanie się między nimi jest uciążliwe. Aby wystawić aplikację trzeba stworzyć:

  • folder wynikowy dla środowisk;
  • pulę aplikacji dla ASP.NET oraz ASP.NET Core – nie może być jedna pula, bo ASP.NET Core nie jest uruchamiany z poziomu .NET CLR, sam zarządza swoimi zasobami. Na domiar mamy jeszcze tryby InProcess oraz OutOfProcess;
  • witrynę dla ASP.NET oraz ASP.NET Core – jedna pula, jedna witryna (dla InProcess jedna pula, jedna witryna, jedna aplikacja);
  • wirtualny folder dla środowisk development, UAT, hotfix.
  • Należy dodać lub nadpisać aplikację dla środowisk deweloperskich. Nie ma potrzeby tworzenia folderu wynikowego dla aplikacji (WebDeploy), gdyż wystarczą fizyczne foldery aplikacji oraz folder wynikowy dla środowiska.

Rozwiązanie szuka folderów z plikami .csproj, gdzie poszukuje web.config dla ASP.NET oraz appsettings.json dla ASP.NET Core. Jeżeli znajdzie taki folder, to stworzy dla niego aplikację w IIS według wytycznych.

Domyślne wartości w skrypcie pozwolą utworzyć środowisko dla wszystkich aplikacji.

Jeśli jednak będziemy chcieli zmienić parametry, to skrypt poniżej na to pozwala.

Azure DevOps

Uruchomienie skryptów z poziomu Azure DevOps nie jest niczym nadzwyczajnym. Wystarczy zainstalować rozszerzenie Cake i wkleić do pliku YAML.

 

Podsumowanie

Cake jest potężnym narzędziem, dzięki któremu można zautomatyzować procesy związane z integracją i wdrożeniem wielu rozwiązań i trzymać się jednego rozwiązania. W następnym artykule pokażę, jak zintegrować ze sobą zarządzanie projektami z Cake oraz jak zbudować własne SDK, rozszerzając znacząco możliwości MSBuild.

Jeśli nie lubisz skryptów i wolisz pisać tylko w jednym języku, polecam sprawdzić NUKE.

Do następnego!

Jeśli masz jakieś pytania, pisz śmiało!

0 0 votes
Article Rating
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jurek Wickowski
4 years ago

O tak. Cake jest świetny.
Ogólnie wizja “Deploy as a Code” jest świetna.
Polecam i pozdrawiam.

Kurs Gita

Zaawansowany frontend

Szkolenie z Testów

Szkolenie z baz danych

Książka

Zobacz również