Continuous Integration

Zabieramy się za dobre praktyki stosowane w trakcie wytwarzania oprogramowania, które zapowiadaliśmy we wpisie o “modnym” DevOps. Dzisiaj – ciągła integracja (ang. Continuous Integration).

 

Continuous Integration… czyli co?

Ciągła integracja (ang. Continuous Integration) to zestaw działań umożliwiających jak najczęstszą aktualizację centralnego repozytorium zmianami, które powstają w trakcie rozwoju oprogramowania. Zakłada się, że taka aktualizacja powinna odbywać się co najmniej raz dziennie, ale im częściej tym lepiej.

CI zakłada, że zintegrowany kod jest działający i użyteczny. Mówiąc scrumowo, powinien być “wdrażalny”.

Takie podejście powoduje przede wszystkim szybką weryfikację ewentualnych konfliktów, jakie mogą wystąpić gdy nad zmianami pracują różne osoby. Pozwala również na weryfikację poprawności rozwiązania uwzględniając zmiany, które mogły zostać dokonane w systemie w tak zwanym międzyczasie.

Zmiany, o których mowa zawsze są nanoszone w centralnym repozytorium na ostatnią, poprawnie zbudowaną, oficjalną wersję systemu. To właśnie na niej dokonywane były testy (czy to manualne, czy automatyczne). To ta wersja była podstawą, którą wykorzystano do zmian w bieżących funkcjonalnościach.

Nie można mówić o Continuous Integration bez procesów automatyzacji budowy nowej wersji środowiska i testów automatycznych. Musimy maksymalnie uprościć stawianie nowej wersji środowiska, jeżeli chcemy integrować się ciągle. Nie obejdzie się także bez automatycznej weryfikacji poprawność zmian dokonanych w kodzie, zanim zostanie on wykorzystany do budowy kolejnej “wdrażalnej” paczki.

Na pewno też, z definicji CI, niedopuszczalne jest rozwijanie oprogramowania w osobnych branchach, które potem trzeba merge’ować. Proces ten bywa bolesny, nie tylko dla deweloperów, ale i dla osób utrzymujących środowiska i wdrażających systemy.

 

CI [si-aɪ]

Ciągła integracja to nie jest termin zarezerwowany dla DevOps. To coś, co powinno być wykorzystywane przy wykorzystaniu każdej metodyki zwinnej. Ba, wyobrażam sobie jego zastosowanie również przy klasycznym podejściu do wytwarzania oprogramowania. Wykorzystanie Continuous Integration pozwala na osiągniecie wielu korzyści, choć może też powodować pewne problemy.

W jaki sposób integrujemy naszą pracę nad kodem? Czy już od samego początku stanowi on całość, czy jest utrzymywany “w izolacji” na maszynach programistów bądź środowiskach testowych do czasu, kiedy padnie komenda “wdrażamy!”?

Implementacja CI zależy od tego, kogo zapytamy, a przede wszystkim od tego, z jakim podejściem pracują te osoby. Dużą rolę będzie grała również wielkość naszego projektu. Inaczej będzie, kiedy nad kodem pracują 1-2 osoby, a inaczej jeśli nasz zespół specjalistów liczy osób -naście, -dziesiąt czy -set.

Zastanawiając się nad sensem Continuous Integration jak na dłoni widzimy, że takie podejście jest nam w stanie znacząco ułatwić sprawy związane z budową czy weryfikacją zbudowanego oprogramowania. Dlaczego więc nie postępowano tak od zawsze?

 

Wady… Jakie wady?!

“Nie ma róży bez kolców”, powiada polskie przysłowie. Również i w tym przypadku, analizując Continuous Integration znajdziemy jego potwierdzenie. Ciągła aktualizacja centralnego repozytorium wiążę się chociażby z koniecznością weryfikacji poprawności naszych zmian lokalnie, zanim jeszcze zostaną wysłane do repozytorium. Zaniechanie tej czynności spowoduje problem z postawieniem nowej wersji systemu, opartej na wprowadzonych zmianach – tzw. broken build.

Jedna z nadrzędnych zasad Continuous Integration mówi, że dopiero po poprawnym postawieniu środowiska programista może zakończyć swój dzień pracy.

Innym, często występującym problemem, jest konieczność rozwiązywania konfliktów w przypadku, gdy kod został zaktualizowany przez innego programistę, w czasie gdy my działaliśmy na starej wersji. To w naszej gestii leży obowiązek rozwiązania konfliktu i doprowadzenie do obu zmian do stanu “używalności” (“wdrażalności” całego systemu).

Trzecim aspektem, o którym warto wspomnieć jest konieczność posiadania dedykowanego środowiska, jego utrzymanie i konfiguracja. To jeszcze nic strasznego, ale warto aby budowa nowej wersji systemu trwała możliwie jak najkrócej. Mówi się nawet o czasie wynoszącym około 10 minut. Długie oczekiwanie to oczywista strata dla wszystkich zaangażowanych. Nie wspominając już o sytuacji, w której zależy nam na szybkim przetestowaniu istotnej dla klienta funkcjonalności.

 

Zalety ciągłego wdrażania

Zasady Continuous Integration mają w założeniu pozwolić nam poradzić sobie ujarzmić najważniejsze ryzyko związane z równoległą pracą nad kodem – integrowanie skończonego kawałka funkcjonalności. Jeśli nie integrujemy się ciągle, nie korzystamy z Continuous Integration, to po zakończeniu kodowania naszej zmiany bardzo trudno będzie nam przewidzieć ile (i czy w ogóle!) będzie istniała możliwość integracji pracy naszego zespołu.

Co więcej, ciągłe wdrażanie pozwala na redukcję ryzyka również w innym obszarze – jakości wytworzonego oprogramowania. Nie ma nic bardziej demotywującego w zespole i bardziej destrukcyjnego w naszych relacjach z klientem niż wadliwy produkt wdrożony na środowisko produkcyjne. Dzięki Continuous Integration jesteśmy w stenie na bieżąco weryfikować poprawność każdej z części wdrażanej funkcjonalności.

CI pozwoli nam również na skrócenie time-to-market, który to czas dla wielu jest kluczowy. I nie ma co się temu w dzisiejszych czasach dziwić.

Dużo łatwiej jest wrócić do poprawy błędu, który powstał poprzez integrację kodu zaktualizowanego wczoraj niż męczyć się z błędem, który dotyczy kodu wdrożonego na zintegrowane środowisko dwa tygodnie temu. Jeszcze gorzej, jeżeli ten błąd jest z nami od dawna i wszyscy pracują na wadliwym środowisku. Wspominaliśmy o tym omawiając dług technologiczny.

 

CI to nie tylko agile

Ideę ciągłego wdrażania można z powodzeniem implementować nie tylko w metodykach zwinnych, ale również w metodykach klasycznych. Podejście to wcale nie wymaga działania zgodnego z agile manifesto. Nie jest wymagany ani podział funkcjonalności na “zjadliwe” części, ani praca iteracyjna, aby możliwe było wykorzystanie Continuous Integration.

Co więcej, możemy w ten sposób łatwo uniknąć wielu problemów, które uniemożliwiłby nam osiągnięcie sukcesu w ostatniej fazie tradycyjnej metodyki czyli wdrożenie funkcjonalności na środowisko docelowe. Skoro realizując projekt nie chcemy korzystać ze zwinnego podejścia, rozważmy chociaż wykorzystanie CI.

Czy wady CI powodują, że ciągłe wdrażanie jest nieekonomiczne lub nieergonomiczne w stosunku do sposobu, w jaki kiedyś radzono sobie z omawianymi problemami? A skąd! Czas poświęcony na opracowanie wydajnego i skutecznego procesu budowy nowej wersji systemu, przygotowanie testów automatycznych i rozwiązywanie konfliktów jest i tak krótszy niż czas poświęcony na integrację pracy po paru miesiącach programowania.

Łukasz Bręk

14 lat doświadczenia w IT, 7 lat doświadczenia w Scrum, PSM, PSPO, Scrum Master zespołów zwinnych, Product Owner, analityk biznesowy, trener Scrum

Click Here to Leave a Comment Below

Leave a Reply: