Jednym z największych wyzwań w rozwoju oprogramowania jest dostarczanie wysokiej jakości rozwiązań programistycznych w możliwie krótkim czasie. Dbanie o jakość w całym projekcie jest najczęściej rolą Quality Assurance (QA). Piastując rolę QA, należy budować strategię i podejmować właściwe decyzje odnośnie sposobu zapewnienia odpowiedniego poziomu jakości kodu.
Wprowadzając i nadzorując procesy, trzeba pamiętać, że konieczna jest bliska współpraca środowisk programistycznych i zespołów testerskich. Do wsparcia należy zaangażować zespoły DevOps, które bazując na doświadczeniu, mogą zaproponować i zbudować odpowiednie środowisko.
W celu spełniania tych wymagań proponuję wdrożenie CI/CD, o którym opowiem w niniejszym artykule.
Wdrożenie CI/CD
Ciągła Integracja (ang. Continuous Integration, CI) i Ciągłe Dostarczanie (ang. Continuous Delivery) to zbiór zasad, wytycznych, kultura pracy i kolekcja dobrych praktyk związanych z pracy nad projektami informatycznymi.
W teorii sprowadza się ona do zasad, w których zespół developerów jest zobligowany do częstszego dostarczania pewnych, przetestowanych i sprawdzonych zmian w kodzie.
Implementacja tych zasad nazywana jest procesem CI/CD i jest uważana za jeden z najlepszych oraz najefektywniejszych sposobów pracy nad projektami informatycznymi.
Ciągła integracja
Ciągła integracja to praktyka polegająca na możliwie częstym i regularnym wprowadzaniu zmian w kodzie do głównego repozytorium, a także każdorazowej weryfikacji zmian poprzez zbudowanie projektu oraz wykonaniu testów jednostkowych. Przydatna jest również statyczna analiza kodu, która małym kosztem szybko wykryje błędy. Znaczenie ciągłej integracji rośnie wraz z wielkością zespołu programistycznego.
Repozytorium
Repozytorium można postrzegać jako wielką księgę. Każdy programista kopiuje ją i dopisuje (czasami usuwa) własne treści. Po zakończeniu swoich prac, księgę trzeba opublikować i scalić, aby mogli pracować na niej inni programiści. Wpisy mogą odbywać się równocześnie przez wiele osób, a do porządkowania wpisów wykorzystuje się systemy kontroli wersji (np. git).
Jeżeli jednak programista wprowadzi jednorazowo zbyt duże zmiany, nie zwracając uwagi na treści wprowadzone w międzyczasie przez innych programistów, mogą pojawić się problemy z integracją, potocznie nazywane „piekłem integracji” (ang. merge hell). W praktyce zdarza się, że rozwiazywanie tych problemów może trwać dłużej, niż przygotowanie wprowadzonej zmiany.
TDD
Ciągła integracja związana jest z wykonywaniem zautomatyzowanych testów jednostkowych zgodnie z metodologią TDD (Test Driven Development). Przed wprowadzeniem zmian do repozytorium należy przetestować swój kod lokalnie. Rozwiązanie to pomaga utrzymać repozytorium w należytym stanie. W przypadku pracy nad większą funkcjonalnością należy – mimo niezakończonej pracy –wprowadzać zmiany do repozytorium możliwie często, korzystając z zaślepek i nie rezygnując z testów jednostkowych.
Kompilacja źródeł powinna odbywać się cyklicznie np. codziennie, a najlepiej nawet po każdej zmianie do repozytorium.
Zalety Ciągłej integracji
Wprowadzenie powyższych praktyk przynosi wiele korzyści m.in.:
- Zmniejszenie kosztów i nakładów pracy niezbędnej do łączenia prac wykonanych przez różne osoby.
- Implementacja prawidłowego procesu pozwala na wczesne wykrywanie usterek.
- Przy większych projektach zmniejsza frustrację wśród programistów.
Czym większy zespół programistyczny, tym większa jest korzyść z wprowadzenia rozwiązania.
Ciągłe dostarczanie
Ciągłe dostarczanie to podejście, w którym zespoły wytwarzają oprogramowanie w krótkich cyklach, zapewniając, że oprogramowanie może być wydane w sposób niezawodny w dowolnym momencie, a sam proces jest wykonywany całkowicie automatycznie. Celem jest tworzenie, testowanie oraz wydawanie oprogramowania z większą szybkością i częstotliwością. Podejście to pomaga zredukować koszty, czas i ryzyko wprowadzania zmian poprzez zwiększenie liczby przyrostowych aktualizacji aplikacji w środowisku produkcyjnym.
Algorytm dla CD
- Najważniejszym elementem algorytmu jest sprzężenie zwrotne, które umożliwia reakcję zespołu developerskiego w razie potrzeby. Kontrola wersji powinna być nadzorowana przez code review. W ten sposób jakość commitowanego kodu jest podnoszona, a dobre nawyki programistyczne są propagowane w zespole.
- Po wprowadzeniu zmian do repozytorium następuje budowanie aplikacji lub jej części, czyli przygotowanie kompilacji paczek z niezbędnymi komponentami np. na różne systemy operacyjne.
- Po kompilacji i zbudowaniu paczek należy przeprowadzić Podstawowe testy akceptacyjne (BAT), dzięki temu mamy pierwsze podstawowe informacje o statusie produktu. Takie testy nazywane są również „smoke testami”.
- Kolejnym etapem jest walidacja i przeprowadzenie szerokiego zakresu testów w tym testów akceptacyjnych użytkownika. W zależności od głębokości testów i potrzeb mogą to być testy nocne (nightly), które pozwalają na zebranie wyników o poranku następnego dnia.
- Jeżeli jest taka potrzeba, można przeprowadzać dłuższe testy które zawierają testy obciążeniowe i wydajnościowe. Należy wówczas uwzględnić fakt, że ten rodzaj testu może trwać kilka dni.
- Na podstawie wyników wszystkich testów następuje decyzja o wydaniu produktu. Kandydata może cechować wysoka stabilność bądź implementacja nowych funkcjonalności. Poprawne przygotowanie przypadków testowych pozwala na eliminację defektów już we wcześniej fazie testowania.
- Dobrym zwyczajem, w przypadku wykrycia nowego defektu jest przygotowywanie nowego testu, który umożliwi wykrycie problemu w przyszłości.
Niewątpliwą zaletą tego CD jest szybsze dostarczanie rozwiązań na rynek, większa produktywność i wydajność pracy programistów i zespołów powiązanych.
Zauważalne jest zwiększenie niezawodności produktu – częste testowanie i rozwijanie bazy testów powoduje dostarczenie produktu o wysokiej jakości.
Ale kto się tym zajmie?
Celem pracy w zespole programistycznym jest wydanie produktu. Konieczne jest zaangażowanie całego zespołu deweloperskiego, managerów produktu raz managerów projektu. Jedną z kluczowych ról w takim procesie odgrywa zespół DevOps.
DevOps – rola w projekcie
DevOps (nazwa powstała z połączenia słów development i operations) jest kulturą organizacyjną, mającą za zadanie stworzyć synergię pomiędzy działami wytwarzania oprogramowania (Dev) i zarządzania systemami (Ops). Ruch DevOps promuje płynną komunikację pomiędzy wszystkimi firmowymi zespołami technicznymi odpowiedzialnymi za tworzenie produktu i wspólne dostarczanie wartości dla klienta. Dzięki temu zmniejsza jednocześnie tarcia, do których często dochodzi w klasycznych organizacjach z wyraźnym podziałem na ludzi tworzących oprogramowanie i administratorów systemów, którzy mozolnie wdrażają stworzone oprogramowanie.
DevOps powinien mieć obszerną wiedzą administracyjną jak i programistyczną. Musi wiedzieć, jak działa sprawny proces CI/CD, a jego wiedza powinna bazować na doświadczeniu. Do zadań należy przygotowanie tzw. Pipline procesu. DevOps musi przygotować infrastrukturę sieciową i sprzętową, narzędzia do monitorowania, budowania. Ważny jest wybór narzędzi testujących (Test Tools). Przy konsultacji z zespołem wymagane są wdrożenia specjalistycznych rozwiązań np. do sprawdzania pokrycia testami kodu, rozwiązań antyplagiatowych, audytu źródeł kodu czy antywirusów. Musi brać pod uwagę cechy specyficzne projektu i pod nie projektować kolejne etapy.
Dobre nawyki przy wprowadzaniu CI/CD
Do dobrych nawyków należy:
- Przynajmniej raz dziennie wprowadzać zmianę na główne repozytorium.
- Starać się wprowadzać zmiany w możliwie małych blokach.
- Oznaczać flagami znaczące nowe funkcjonalności.
- Polegać na automatyzacji stabilnych testów.
- Naprawa buildu ma najwyższy priorytet.
- Używać zaślepek, jeśli nie udało się przygotować całej funkcjonalności.
- Współpracować przy przeglądzie wprowadzanego kodu (Code Review).
- Budowanie oraz BAT nie powinny trwać dłużej niż godzinę.
- Każdy defekt powinien być pokryty przypadkiem testowym.
- Wyniki testu powinny jasno przekazać istotę odnalezionego problemu.
- Jeżeli build nie działa, nikt nie powinien wprowadzać nowych zmian.
- Zespół może zadecydować, kiedy odrzucić psującą zmianę, a kiedy oflagować i wyłączyć funkcjonalność.
- Utrzymanie zdrowego procesu jest obowiązkiem wszystkich użytkowników procesu.
- Wszystkie powtarzalne ręcznie operacje powinny być automatyzowane.
- CI/CD jest procesem, co oznacza, że zawsze jest możliwość udoskonalenia.
- Jeżeli jest wiele do udoskonalenia, należy zacząć od najprostszych rzeczy.
Trudności realizacyjne
Oczywiście, wprowadzenie kolejki (pipline) ma też parę wad.
Szczególnie w dużych korporacjach samo projektowanie procesu może zająć dużo czasu. Chociaż podstawy są podobne, to nie da się przygotować jednego uniwersalnego procesu dla każdego projektu.
Również przygotowanie testów może być czasochłonne. Konieczna jest analiza wymagań projektowych, które mogą być wsparciem dla zespołu przygotowującego testy. Dodatkowo, trudna jest zmiana nawyków programistów. Częste commity czy code review mogą wydawać się nadmiarową pracą. A pełna automatyzacja może zabrać pracę testerom manualnym.
Kilka słów na koniec
Zespół musi pamiętać, że każdy jest częścią CI/CD i na dbaniu o sprawne utrzymanie procesu korzystają wszyscy. Warto poświęcać chwilę na codziennych spotkaniach (Daily) i poruszać status kolejki testów.
Zostaw komentarz