TeamCity : pre-tested commit
Czyli w jaki sposób, prosto i skutecznie, rozwiązać problem commit'owania niedziałającego kodu do repozytorium, a tym samym zwiększyć szybkość pracy całego zespołu.
W obecnych czasach trudno jest, tworząc komercyjne rozwiązania, wyobrazić sobie projekty, które nie stosują się (czasem nawet nieświadomie) do zbioru praktyk Fowlera, powszechnie znanych pod nazwą Continuous Integration. Najważniejszym celem tych praktyk jest redukcja czasu (a co za tym idzie także i kosztów) wdrażania zmian do projektu poprzez wczesną i częstą (ich) integrację. Zmiany te są efektem pracy wielu programistów w zespole. Idea Continuous Integration liczy sobie blisko 10 lat. Przez ten czas powstało wiele narzędzi wspomagających nas – programistów - w ciągłym wdrażaniu tej idei w życie (we własnych projektach).
Wśród rozmaitych aplikacji wspierających idee Continuous Integration bardzo ważne miejsce zajmują serwery integracji, w skrócie serwery CI. Pozwalają one na automatyczne budowanie projektów, uruchamianie testów oraz bardzo szybkie informowanie o napotkanych błędach i awariach. Są to oczywiście tylko ich podstawowe możliwości. Najbardziej zaawansowane systemy oferują dużo więcej interesujących i użytecznych funkcji.
Jednym z takich zaawansowanych narzędzi, które na przestrzeni ostatniego roku zyskało sobie rzesze użytkowników, jest TeamCity. Niewątpliwym tego powodem jest unikatowa funkcjonalność, jaką oferuje swoim użytkownikom: pre-tested commit.
Aby w pełni docenić jej zalety, na początku przypomnę pokrótce standardowy scenariusz codziennej pracy programisty:
1. Update kodu projektu z repozytorium;
2. Zmiany w paru klasach (programowanie właściwe :-)
3. [opcjonalnie] Weryfikacja zmian – uruchomienie testów jednostkowych;
4. Commit zmian do repozytorium kodu (poprzedzony update'em – o to dba samo repozytorium);
5. Automatyczne pobranie przez serwer CI najnowszej wersji źródeł z repozytorium i rozpoczęcie budowy projektu;
6. [opcjonalnie] Sprawdzenie czy serwer CI poprawnie zbudował kod z wprowadzonymi zmianami
Wszyscy tak pracujemy. Można więc zapytać: cóż złego jest w takim trybie pracy, tym bardziej, że jest on tak powszechnie stosowany? Głównym problemem (smell'em) jest to, że nawet jeśli programista uruchomił testy jednostkowe (które zakończyły się sukcesem) przed commit'em swojego kodu, to nie mamy żadnej gwarancji, że ten sam kod na serwerze CI też się skompiluje i przejdzie testy. Zapewne każdemu z nas przydarzyła się kiedyś taka sytuacja. Przyczyn jej może być wiele. Najczęstszą są różnice pomiędzy środowiskiem developerskim a tym, gdzie znajduje się serwer CI. Mogą to być "zahardkodowane" ścieżki, różne wersje bibliotek czy inne niejawne założenia, jak np. dostęp do zasobów zdalnego dysku. Bywa, że do jednego build'a trafią zmiany z paru commit'ów, które wprawdzie osobno działały, ale razem już nie chcą. Czasem powód jest bardziej trywialny: nie wszystkie zmienione klasy zostały wysłane do repozytorium, co powoduje, że kod najzwyczajniej w świecie się nie kompiluje. W tym momencie zaczyna się zwykle szukanie winnego w zespole: tego, który umieścił crap w repozytorium. O ile znalezienie go nie stwarza problemu, to gorzej bywa jednak z poprawieniem samego błędu. W najgorszym przypadku praca całego zespołu zostaje zablokowana i to wszystko z powodu jednego niefortunnego commit'u.
Pomysłów na rozwiązanie tego problemu jest co najmniej kilka: od wprowadzenia wysokiej dyscypliny wśród programistów po skomplikowane rozwiązania SCM jak stable trunk (które wymagają od programistów nie mniej dyscypliny, a przy tym dużego nakładu pracy).
Inżynierowie z JetBrains wymyślili unikatowe rozwiązanie tego problemu. Zmodyfikowali oni powyższy scenariusz pracy w taki sposób, aby niedziałający kod nie mógł znaleźć się w repozytorium, a przy tym nie był uciążliwy dla jego użytkowników. Do tego właśnie służy funkcja pre-tested commit, którą między innymi oferuje TeamCity.
Scenariusz pracy programisty z TeamCity wygląda następująco:
1. Update kodu projektu z repozytorium;
2.Dokonanie zmian w paru klasach (programowanie właściwe :-)
3. Wysłanie zmienionych plików do TeamCity (za pomocą plugin'a w IDE);
4. Rozpoczęcie procesu budowania projektu przez TeamCity z wykorzystaniem plików przesłanych przez programistę oraz plików z repozytorium;
a) umieszczenie w repozytorium wysłanych plików, jeśli build zakończył się sukcesem;
b) brak zmian w stanie repozytorium, jeśli build się nie udał;
5. Poinformowanie programisty o stanie jego build'a.
Jak widać, w takim trybie pracy w repozytorium znajdzie się tylko sprawdzony kod. Jak bardzo, zależy to już tylko od naszych testów. Mamy jednak gwarancję, że błąd jednego programisty nie zablokuje całego zespołu i nie spowoduje przestojów w pracy.
W praktyce korzystanie z funkcji pre-tested commit jest bardzo proste i w pewnym stopniu przypomina korzystanie z wtyczek repozytoriów kodu. Poza działającą instancją serwera TeamCity wymagana jest wtyczka do IDE. W chwili pisania tego artykułu wspierane były środowiska IntelliJ IDEA oraz Eclipse. W tym ostatnim plugin dostarcza cztery nowe zakładki, z których najważniejsza to Remote Run. To właśnie ona pozwala na wykorzystanie funkcji pre-tested commit. Można z niej zdalnie uruchomić build z "prywatnymi" zmianami programisty, który nazywany jest Personal Build (prywatny build).
Na zakładce Remote Run można wybrać:
- pliki ze zmianami wychodzącymi;
- konfiguracje builda (uprzednio stworzoną na serwerze TeamCity), w której zmienione pliki mają być wykorzystane.
Zaznaczając opcje Commit after build(s) finish, pliki ze zmianami zostaną wysłane do repozytorium tylko i wyłącznie po pomyślnym "przejściu" build'a. I to jest właśnie sedno pomysłu pre-tested commit – do repozytorium trafią tylko te pliki, które już raz przeszły testy na serwerze CI.
Warto zwrócić uwagę, że Personal Build może być wykorzystany do zwiększenia produktywności programisty (czy wręcz jako alternatywa dla zakupu szybszego komputera dla niego). Korzystając z niej, programista może zdalnie, na serwerze, uruchamiać swoje testy (budować projekt) i w tym samym czasie nadal pracować nad dalszą częścią swojego rozwiązania. Tryb jego pracy nie jest przerywany przez oczekiwane na zakończenie lokalnego build'a, który często bywa czaso- i zasobochłonny.
Producentem TeamCity jest firma JetBrains, znana przede wszystkim jako producent IntelliJ IDEA. TeamCity to produkt komercyjny, pomimo to dostępny za darmo w wersji Professional. Wersja ta charakteryzuje się ograniczeniem ilości użytkowników i konfiguracji projektów (build'ów) do 20 oraz Build Agents do 3. Ilość Build Agents określa maksymalną możliwą ilość równolegle trwających procesów budowy projektów. Powyższe ograniczenia nie są jednak na tyle poważne, aby mogły przeszkodzić w pomyślnym wdrożeniu tego produktu w małych i średnich projektach zupełnie za darmo.
Podsumowując TeamCity wydaje się być nowatorskim produktem w świecie serwerów CI. Rozwiązanie to może w prosty sposób przyczynić się do ograniczenia problemów związanych z ciągłą integracją, na które napotykają się wręcz codziennie zespoły programistów tracąc czas i pieniądze. Wykorzystanie funkcji pre-tested commit jest łatwe i nie wymaga od programisty drastycznych zmian w jego codziennym trybie pracy, dzięki czemu jest tanie i realne do wprowadzenia w życie (nie napotkamy fali sprzeciwów w zespole).
Nie ma jeszcze komentarzy.