Ciągła integracja dla każdego – instalacja i konfiguracja serwera TeamCity
TeamCity jest to serwer ciągłej integracji udostępniany przez firmę JetBrains, znaną m.in. dzięki Resharperowi czy też IntelliJ IDEA. Z kolei ciągła integracja określa podejście w którym zmiany są integrowane z działającym już systemem. Jakie są profity z korzystania z takich serwerów? Głównie chodzi o wczesne wykrycie konfliktów między właśnie dokonanymi zmianami w kodzie a już istniejącą, działającą aplikacją. Oprócz tego w łatwy sposób możemy publikować każdą nową wersję np. na zakończenie każdego ze sprintów w metodyce SCRUM. W poniższym artykule opiszę w jaki sposób rozpocząć pracę z jednym z najpopularniejszych serwerów CI.
Przegląd sytuacji
Przygotowałem prostą, testową aplikację opartą o ASP.NET MVC, która docelowo będzie budowana przez TeamCity. Do kontroli wersji używam Gita (dokładniej będzie to Gitlab lecz nie ma to teraz większego znaczenia). Dysponuję również serwerem z czystą instalacją Windows Server 2012.
Zaczynamy
Pierwszym krokiem będzie oczywiście pobranie instalatora z oficjalnej strony TeamCity. W czasie kiedy piszę ten post najnowszą wersją jest wersja 9.1 i takiej też będę używał.
NOTKA: TeamCity w podstawowej wersji jest darmowe i dla naszych potrzeb taka licencja w zupełności wystarczy:
By default, each TeamCity installation runs under a Professional Server license including 3 build agents. This license is provided for free with any downloaded TeamCity binary and gives you full access to all product features with no time limit. The only restriction is a maximum of 20 build configurations.
Instalację przeprowadza znany i lubiany wszystkim “czarodziej” (ang. wizard ;)). Po przejściu kilku pierwszych ekranów oraz akceptacji licencji, instalator pyta się o ścieżkę, gdzie znajdować się będzie cały serwer wraz z “build agentami”.
NOTKA: Jeśli dysponujemy dwoma dyskami (np. HDD i mniejszy SSD) proponuję wybrać folder na większym dysku, gdyż po jakimś czasie dane TeamCity potrafią spuchnąć. Oczywiście JetBrains udostępnia mechanizmy oszczędzania tegoż miejsca jednakże zaawansowana konfiguracja jest tematem na oddzielny wpis.
W kolejnym kroku wybieramy komponenty do zainstalowania. Jako, że mamy dostęp do jednej maszyny instalujemy serwer wraz z build agentem. W bardziej zaawansowanych konfiguracjach możemy rozdzielić serwer zarządzający od agentów poprzez oddelegowanie budowania aplikacji na inne maszyny.
Ważną sprawą jest wybranie portu na którym będzie działał serwer TeamCity. Domyślnie ustawiony jest on na 80, jednakże w przyszłości może on kolidować z aplikacjami, które będziemy chcieli upubliczniać w sieci. Bezpiecznym wyborem będzie np. port 9000.
Na następnym ekranie przedstawiona jest konfiguracja nowo zainstalowanego build agenta wraz z opisem poszczególnych opcji. Konfigurację można dostosować właśnie w tym momencie lecz także można to zrobić po instalacji przez plik konfiguracyjny.
W następnym krokach instalator pyta jakie konto ma być używane do działania usługi serwera i agenta. Domyślnym wyborem jest konto użytkownika i taką też opcję wybieramy. Na następnym ekranie podajemy odpowiednie informacje (domena, nazwa użytkownika i hasło) oraz przechodzimy na następny ekran, gdzie wybieramy opcję uruchomienia obydwu usług. Instalacja jest zakończona.
Daleko jeszcze?
Dalszą konfigurację przeprowadzamy poprzez interfejs webowy serwera TeamCity. Instalator na ostatnim ekranie pytał nas czy chcemy uruchomić przeglądarkę. Jeśli odznaczyliśmy tę opcję musimy uruchomić ją sami i wpisać adres serwera (tu: http://localhost:9000). Wyświetlony zostanie ekran powitalny, na którym jesteśmy proszeni o podanie ścieżki, gdzie serwer TeamCity będzie przechowywał swoje dane (zostawiłem ścieżkę domyślną).
Kolejnym krokiem jest wybór bazy danych, która będzie służyć do przechowywania różnych informacji przez serwer TeamCity. Domyślnym wyborem jest baza wbudowana, jednak jak można przeczytać poniżej, autorzy nie zalecają używania jej do środowisk produkcyjnych. Póki co możemy pozostać przy wyborze domyślnym – po czasie możemy migrować na inne rozwiązanie.
Po zaakceptowaniu kolejnej licencji oraz utworzeniu konta użytkownika, lądujemy na ekranie głównym serwera. Na razie nie dzieje się zbyt wiele, gdyż brakuje nam założonych projektów. Tak więc wciskamy przycisk “Create project”. Wyświetlony zostanie ekran, na którym musimy podać nazwę projektu (u mnie jest to “TeamCity-demo”), zatwierdzamy przyciskiem “Create” i aplikacja przenosi nas na ekran konfiguracji projektu.
Klucze SSH
Aby połączyć się z repozytorium Gita (tutaj konkretnie jest to Gitlab) potrzebujemy wrzucić do TeamCity klucz prywatny. Wykorzystałem tutaj funkcjonalność Gitlaba pod tytułem “deploy keys”, gdzie możemy utworzyć klucz, który będzie wykorzystywany tylko do pobierania zmian z repozytorium.
NOTKA: Do wygenerowania odpowiednich kluczy, które będą używane w Gitlabie i TeamCity wykorzystałem program PuTTYgen według tej instrukcji.
Połączenie z repozytorium
Po dodaniu klucza przechodzimy na zakładkę “VCS roots” gdzie zestawimy połączenie z odpowiednim repozytorium.
Formularz jest dosyć standardowy i myślę, że nie trzeba tłumaczyć poszczególnych pól. Ważnym jest aby wybrać typ repozytorium zgodnie z tym czego używamy (jeśli jest to Git to naturalnie wybieramy Git). Podajemy odpowiedni “Fetch URL” (adres do repozytorium) oraz ustawiamy rodzaj uwierzytelnienia.
NOTKA: Jeśli chcemy łączyć się poprzez SSH wybieramy z pola “Authentication method” opcję “Uploaded key”. Następnie w polu “Uploaded key” wyszukujemy wcześniej dodany przez nas klucz SSH.
Jeśli wymagane pola zostały poprawnie uzupełnione klikamy na samym dole przycisk “Test connection” i …
Mamy połączenie! Zapisujemy zmiany i przechodzimy do tworzenia konfiguracji builda.
Coraz bliżej…
Co nam pozostało? Określić co ma się budować, kiedy i w jaki sposób. W tym celu utworzymy nową konfigurację poprzez wybranie opcji “Create build configuration” na ekranie ustawień projektu. Na kolejnych ekranach podajemy nazwę konfiguracji (odpowiednio do czego jej potrzebujemy np. master, prod, stage, QA, dev, fix itd.) oraz ustawiamy połączenie do repozytorium, które definiowaliśmy w poprzednich krokach.
Przechodzimy na ekran, gdzie musimy określić jakie kroki będą składały się na proces budowania naszej aplikacji. TeamCity jest tu bardzo pomocne gdyż, na podstawie plików umieszczonych w repozytorium, potrafi samo wykryć jakie kroki będą nam potrzebne. Jak widać na powyższym zrzucie wykryty został jeden krok, którego użyję do aktualnej konfiguracji.
1 push = 1 build?
Pozostało nam określenie w jakich momentach build ma zostać uruchamiany. W tym celu przechodzimy na zakładkę “Triggers” gdzie utworzymy nowy wyzwalacz.
Domyślnie TeamCity podpowiada nam aby build był wywoływany bezpośrednio po każdym wypchnięciu zmian do repozytorium bez wykorzystania tak zwanego “Quiet mode”.
NOTKA: “Quiet mode” jest to tryb w którym TeamCity oczekuje po każdym wypchnięciu określony czas w celu dołączenia innych nadchodzących zmian do builda.
Osobiście odznaczam opcję “Trigger a build on each check-in” oraz ustawiam “Quiet mode” na 60 sekund. W zależności od środowiska ma to swoje wady i zalety. Na przykład jeśli scalamy zmiany z gałęzi “dev” do “prod” i do scalenia mamy 60 commitów to build zostanie rozpoczęty 60 razy! W zależności od rozbudowania aplikacji może to trwać całkiem dużo czasu, jednakże jeśli coś pójdzie nie tak (podczas procesu wystąpi błąd) wiemy od razu, które (czyje :)) zmiany go wywołały.
Hello world!
Po zapisaniu wszystkich zmian podstawowa konfiguracja została ukończona. Możemy przejść na główny ekran oraz przy utworzonej konfiguracji kliknąć “Run”.
No i się wysypało… O co chodzi? Jak informuje nas ostrzeżenie, nie mamy kompatybilnych agentów. Związane jest to z konfiguracją kroków budowania. TeamCity wykryło krok “Visual Studio (sln)”, którego użyliśmy, jednakże wymaga on zainstalowanego Visual Studio (np. wersji Community).
Zainstalowałem Visual Studio, czy to wszystko?
Sprawdźmy. Ponownie wciskamy przycisk “Run” i naszym oczom ukazuje się…
Błąd. Po przejściu do dziennika builda, otrzymujemy informację, że na komputerze nie ma wymaganych przez projekt paczek NuGeta. Co pominęliśmy? Znowu chodzi o konfigurację “Build steps”. TeamCity nie podpowiedział, że do tego typu projektu potrzebny jest dodatkowy krok poprzedzający właściwy build a mianowicie “NuGet installer”. Przechodzimy więc ponownie na zakładkę dodawania kroku i z listy wybieramy “NuGet installer”. Musimy jeszcze wskazać TeamCity ścieżkę do NuGeta (którego de facto nie mamy), dlatego przechodzimy na ekran “NuGet settings”.
Na tym ekranie wybieramy odpowiednią wersję NuGeta (np. najnowszą), zaznaczamy “Set as default” oraz wciskamy przycisk “Add”. Następnie wracamy na ekran dodawania kroku z NuGetem, gdzie pozostało nam wskazać ścieżkę do pliku .sln. Zapisujemy konfigurację.
Ostatnim krokiem jest zmiana kolejności wykonywania kroków. Musimy wskazać, że najpierw będą ściągały się paczki z NuGeta a następnie wywoływany będzie właściwy build.
Jeśli wszystko przebiegło poprawnie, po kolejnym buildzie powinien ukazać się nam obraz podobny do poniższego.
Szczególną uwagę należy zwrócić na zieloną ikonkę obok której widnieje napis “Success”, który informuje o poprawnym wykonaniu wszystkich skonfigurowanych kroków.
Co dalej?
Właśnie zakończyliśmy podstawową konfigurację serwera ciągłej integracji. Podczas kolejnych “pushów” do repozytorium proces budowania będzie wywoływany i po jego zakończeniu użytkownicy dostaną informację o jego powodzeniu (lub też przeciwnie).
W kolejnych wpisach opiszę proces publikowania aplikacji wraz z uruchomieniem migracji bazy danych oraz testów jednostkowych.