trzy drogi devops

Trzy drogi DevOps i co z nich wynika

Książka “Projekt Feniks. Powieść o IT, modelu DevOps i o tym, jak pomóc firmie w odniesieniu sukcesu” stanowi idealny łagodny wstęp do tej metodyki. Jestem przekonany, że po jej przeczytaniu czytelnik nie raz i nie dwa krzyknie “ależ ja spotkałem podobnego człowieka/sytuację!”. Definiuje ona i pokazuje w działaniu trzy główne zbiory zasad DevOps (nazywane też drogami DevOps). Dzisiaj właśnie o tych zasadach.

Droga trzecia, czyli uczenie się

Zasady zawarte w trzeciej drodze rekomendują stworzenie w organizacji (rozwoju i operacji) takiej kultury organizacyjnej i atmosfery która wspiera doskonalenie dwóch wcześniejszych procesów – w tym otwarte wskazywanie istniejących w nich błędów/ograniczeń. Rekomendacje zawarte w tej drodze mają najmniej techniczny charakter, a są najbardziej związane z praktyką zarządzania zespołami pracowników. 

Wywodzą się one z obserwacji, że w sztywnych, zbiurokratyzowanych, czy zarządzanych “autorytarnymi” metodami strukturach zanika inwencja twórcza, pracownicy stają się obojętni na funkcjonowanie systemu jako całości i koncentrują się na pilnowaniu “własnego ogródka”. W skrajnych przypadkach takie sytuacje prowadzą do rozpowszechnienia się przekonania, że “nic ode mnie nie zależy” oraz praktyki tworzenia przy wykonywaniu każdej czynności niezbyt ładnie nazywanych tzw. “d…chronów”.

Taki stan rzeczy bardzo utrudnia skuteczne wdrożenie i funkcjonowanie DevOps w organizacji. W związku DevOps sugeruje tu wiele różnych mechanizmów mających przeciwdziałanie powyższym zjawiskom. Warto tu wymienić kilka podstawowych tematów, na które kładzie nacisk DevOps:

  • Popieranie przekształcania lokalnych odkryć w globalne usprawnienia.

Organizacja powinna wspierać pracowników, którzy udoskonalili coś w swoich własnych obszarach, umożliwiając im jednocześnie rozpowszechnianie tej wiedzy i wdrażanie udoskonaleń w innych miejscach strumienia wartości technologii. Oczywiście, takie stanowisko jest popierane werbalnie przez wszystkich i zawsze, ale praktyka i sprzeczne interesy różnych grup w procesie często stoją na przeszkodzie rozpowszechnianiu się dobrych rozwiązań. Kluczowym staje się stworzenie systemu i klimatu który przeciwdziała takim blokadom bez jednoczesnego tworzenia dodatkowych konfliktów.

  • Tworzenie kultury organizacyjnej która popiera uczenie się.

Poprzez uczenie się rozumiane są tutaj nie wszelkiego rodzaju szkolenia, ale uczenie się na podstawie efektów swojej codziennej pracy i swoich pomysłów – co ważne, zarówno na podstawie sukcesów, jak i porażek. Jeśli pracownicy boją się konsekwencji organizacyjnych i społecznych każdego, nawet najmniejszego niepowodzenia, zamiera jakakolwiek własna inwencja.

  • Tworzenie kultury bezpieczeństwa (ang. just culture – kultura sprawiedliwego traktowania).

Rekomendacja ta sprowadza się zasadniczo do odpowiedniego typu reakcji na porażki (np. awarie systemu). Zaleca ona koncentrowanie się na poszukiwaniu metod szybkiego naprawienia problemu i zapobieganiu jego powtórzeniu zamiast poszukiwania winnych jego wystąpienia (co łatwo przeradza się w “polowanie na czarownice”).

  • Wdrażanie technik badania reakcji organizacji na awarie produkcyjne.

DevOps rekomenduje tu wręcz organizowanie ćwiczeń w reakcji na symulowane awarie (tzw. technika “chaos monkey” wykorzystywana min. w Netflix).

  • Zarezerwowanie czasu na prace rozwojowe i przekazywanie wiedzy. Aby realizować wszystkie wyżej wymienione działania, pracownicy potrzebują czasu. W pełni zajęci “bieżączką” pracownicy nie będą wykazywać większej inwencji, nawet jeśli stworzy im się do tego idealne warunki we wszystkich innych obszarach.

Jak widać, tematy opisywane przez trzecią drogę należą do repertuaru zarządczych technik miękkich. Wymieniono tu tylko kilka z nich, zapewne jeszcze kolejne jest w stanie wskazać każda osoba mająca doświadczenie w zarządzaniu zespołami ludzkimi.

Szczegóły, czyli na czym to technicznie polega

Czytelnik, który przebrnął przez poprzednie rozdziały mógł odnieść wrażenie, że Devops ma niewiele wspólnego z jakimikolwiek współczesnymi narzędziami wsparcia procesu produkcji. Jest to oczywiście nieprawda, natomiast prawdą jest że wdrożenie wyłącznie narzędzi, bez zmienienia sposobu działania organizacji i co najważniejsze, panującej w niej mentalności, nie przyniesie wielkiej poprawy. Naturalnie, zmiany na plus się pojawią, bo zawsze lepiej jest mieć automatyczny proces ciągłej integracji niż go nie mieć. Ale bez zidentyfikowania, gdzie leżą główne czynniki opóźniające bieg strumienia wartości technologii, znaczna część pracy i inwestycji w rozwiązania techniczne mające umożliwić wdrożenie DevOps w organizacji zapewne się zmarnuje. Samo wdrożenie DevOps w organizacji jest ogromnym tematem i nie będzie tu poruszane.

Niniejszy rozdział jest poświęcony narzędziom, które zwykle wspierają DevOps na różnych etapach procesu produkcji i funkcjonowania oprogramowania (jak to zostało powiedziane wcześniej – strumienia wartości technologii). 

Niniejszy przegląd ma charakter siłą rzeczy nieco subiektywny i nie pretenduje w żadnym razie do jakiejkolwiek kompletności, choćby z powodu bardzo szybkiej ewolucji narzędzi w większości z omawianych obszarów. 

Kolejne części tego rozdziału skupią się na dość hasłowo potraktowanych procesach (czytelnik może znaleźć ich opisy w większości książek z obszaru inżynierii oprogramowania) pogrupowanych zupełnie umownie w zależności od ich orientacyjnego położenia w pojedynczym przebiegu strumienia wartości technologii i o wspierających te procesy narzędziach. Należy tu jednak podkreślić, że proces DevOps jest ze swojej zasady cykliczny i najczęściej przedstawiany jest jak niżej:

cykl devops

Za DevOps, źródło: Pease, Jeremy. 2017. „DevOps Part 1: It’s More Than Teams.” Contegix. June 9 (obecnie niedostępne)

Takie podejście jest w oczywisty sposób implementacją tzw. cyklu Deminga (zobacz) znanego z teorii zarządzania.

Planowanie i zarządzanie pracą

Narzędzia, które wspierają całość zarządzania pracami projektowymi (czyli planowanie, przydzielanie i monitorowanie realizacji zadań – zgodnie z zasadą: niech praca będzie widoczna! ), są w dużej części współdzielone z innymi metodykami zwinnymi. Jako takie nie są więc charakterystyczne dla DevOps.

Zdaniem autora należy tu wymienić dwa najważniejsze:

  • JIRA to narzędzie wyprodukowane wiele lat temu przez firmę Atlassian służące do śledzenia zadań (z angielska: issue tracker). Choć na początku jego rozwój wydawał się nieco chaotyczny, z czasem osiągnęło ono naprawdę wielkie możliwości połączone ze znakomitą elastyczności i możliwościami zarówno integracji i innymi narzędziami, jak i rozszerzania przez mechanizm wtyczek (ang. plugins).
  • ….oraz tablica korkowa z karteczkami reprezentującymi zadania. Prosta, zawsze widoczna i dostępna oraz odporna na awarie infrastruktury. W dobie telefonów komórkowych łatwa do dokumentowania – tym samym śledzenia zmian, choć słabo poddająca się automatyzacji.

Metodyka DevOps zwraca uwagę na jeden aspekt używania tablic kanban – niezależnie od tego, w jakim narzędziu są one zaimplementowane. Do listy faz na tablicy kanban należy włączyć również te powszechnie łączone z operacjami – takie jak np. wdrażanie czy konfigurowanie środowiska (oczywiście, jeśli jest to uzasadnione cechami projektu). 

Początek strumienia wartości technologii

Zanim przejdziemy do bardziej szczegółowego omówienia narzędzi do wsparcia kodowania, budowania i testowania, warto zwrócić uwagę na to czego nie ma w tej części. A nie ma narzędzi wspierających jakiekolwiek prace mające miejsce przed rozpoczęciem kodowania – na przykład zbieranie wymagań klienta (przykładowo w postaci “user stories”), czy prace projektowe nad architekturą rozwiązania. Wynika to oczywiście ze specyfiki metodyki DevOps i tego na jakie elementy kładzie ona nacisk.

Kodowanie

Omawiając tematu kodowania w aspekcie metodyki DevOps warto się skoncentrować na jednym konkretnym aspekcie tej pracy. Jest nim korzystanie programisty z repozytorium kodu źródłowego (tzw. “systemu kontroli wersji” – ang. version control system, VCS). To, jakie możliwości daje narzędzie, w którym realizowane jest zarządzanie kodem źródłowym, w dużym stopniu rzutuje na to, jak sprawna i elastyczna będzie praca zespołu wykonawczego. A w szczególności, ile czasu członkowie tego zespołu będą zużywać na czynności czysto administracyjne związane z utrzymaniem spójności kodu wytwarzanego przez wiele osób.

Niekwestionowanym standardem w tym obszarze jest obecnie Git. Narzędzie to, będące rozproszonym systemem kontroli wersji (ang. distributed version control system) uzyskało w ciągu ostatniej dekady na tyle dominującą pozycję, że można zaryzykować tezę, iż w ciągu najbliższych paru lat spodziewać się należy pojawienia się pokolenia programistów znających z praktyki wyłącznie to rozwiązanie.

Zalety Git’a

Warto wymienić w tym miejscu te cechy Git’a, które wspierają postulowaną przez DevOps dbałość o sprawny przepływ strumienia wartości technologii, czyli zwyczajnie sprawne przekazywanie kodu ze stacji roboczej programisty do dalszych etapów produkcji. 

Najważniejsze z tych cech to:

  • Lokalny charakter Git’a – większość operacji Git wykonywane jest na stacji roboczej posiadającej własne lokalne repozytorium (stąd “rozproszoność” systemu). Dopiero gdy programista jest przekonany, że wyprodukowany kod nadaje się do upublicznienia poprzez przekazanie go do centralnego repozytorium kodu. Takie podejście w wielkim stopniu porządkuje pracę ułatwiając używanie “atomów zmian”, czyli takich ich fragmentów, które tworzą pewną całość. Jednocześnie, pracując wyłącznie na repozytorium lokalnym, programista nie traci nic z zalet mechanizmów kontroli wersji.
  • Istnienie standardu struktury repozytorium – tzw. Git flow (zobacz). Ułatwia kontrolę zawartości wydawanych wersji. Zmniejsza “koszty wejścia” w projekt. Promuje standardowość rozwiązań, a więc reużywalność gotowych narzędzi.
  • Tanie korzystanie z gałęzi (ang. branches). Rozwijanie zmian w gałęziach promuje “atomowość” zmian, możliwość ich równoległego wytwarzania przez wiele osób i zespołów, a w końcu kontrolę tego co ma zawierać wydawana wersja aplikacji.
  • Zmniejszenie ilości problemów pojawiających się przy łączeniu kodu (ang. merging). Pozwala zaoszczędzić naprawdę wiele czasu i frustracji.
  • Git umożliwia budowanie sieci repozytoriów. Struktura gwiaździsta, czyli repozytorium centralne – repozytoria lokalne nie jest jedyną możliwą! Jest to rzadko wykorzystywana możliwość dająca możliwość sprawnego zarządzania naprawdę złożonymi rozwiązaniami realizowanymi przez wiele zespołów. 

Git stał się na tyle ważnym narzędziem, że powstało wiele systemów, które traktują go jako bazę do budowania rozwiązań integrujących albo wręcz obejmujących również inne elementy infrastruktury wspierającej proces wytwórczy (ang. software development toolchain). Z najpopularniejszych można tu wymienić trzy: 

  • GitHub – rozwiązanie chmurowe pozwalające tworzyć i zarządzać zarówno darmowymi repozytoriami jak i rozwiązaniami komercyjnymi.
  • BitBucket – rozwiązanie chmurowe (możliwe również do zainstalowania w chmurach prywatnych) firmy Atlassian pozwalające nie tylko zarządzać wieloma repozytoriami Git, ale również integrować te repozytoria z wieloma zewnętrznymi narzędziami (takimi jak choćby JIRA).
  • GitLab – pełna platforma wspierająca metodykę DevOps.

Oczywiście, nie ma rozwiązania bez wad i Git również je posiada. Choć oczywiście ich lista zależy w pewnym stopniu od indywidualnych preferencji. Przykładowo, Git nie ułatwia procesu przesuwania znaczników (ang. tag), a wręcz utrudnia synchronizację efektów tego procesu pomiędzy repozytoriami. Pewne osoby uważają to za wadę (można do nich zaliczyć autora), inne twierdzą że jest to uzasadnione ograniczenie.

Budowanie

Procesy budowy wchodzący w skład ciągłej integracji (ang. continuous integration – w skrócie “CI” ) rozpoczyna sekwencję działań mających miejsce już poza stacją roboczą programisty i kluczowych z punktu widzenia przemieszczanie się strumienia wartości wartości technologii do dalszych do dalszych etapów produkcji. Drugi z kluczowych składników procesu ciągłej integracji, czyli testowanie, jest opisany w kolejnym rozdziale.

Cechy, które powinien posiadać dobry proces CI:

  • Powinien być w pełni automatyczny i bezobsługowy. W szczególności, musi automatycznie uruchamiać się w reakcji na zmiany w części gałęzi repozytorium przeznaczonej do integracji (zobacz. np. opis gałęzi “develop” w Git flow).
  • Powinien zawierać kroki związane zarówno z budową aplikacji, jak i jej testami automatycznymi (zwykle są to testy jednostkowe).
  • Powinien obejmować automatyczne instalowanie stworzonej dystrybucji aplikacji na przeznaczonym do tego środowisku. Jest to pierwszy krok potrzebny do przekształcenia ciągłej integracji w opisane dalej ciągłe dostarczanie.
  • Powinien automatycznie uruchamiać generowanie wymaganych raportów (min. o jakości kodu) i przekazywanie ich do systemów dedykowanych do ich przechowywania.
  • Na koniec działania powinien wybranym kanałem (zwykle email) informować zespół o sukcesie, bądź niepowodzeniu procesu – wraz z podaniem szczegółów w taki sposób który umożliwia sprawcom problemów szybkie ich naprawienie.

Dobrze funkcjonujący proces ciągłej integracji daje wiele korzyści. Z punktu widzenia metodyki DevOps najważniejszymi z nich są umożliwienie wykrywania błędów na bardzo wczesnym etapie wytwarzania, co zmniejsza koszty ich obsługi i eliminuje daleko idące konsekwencje późnego ich wykrycia.

Narzędzia, w których implementuje się proces ciągłej integracji służą też zwykle do koordynacji obsługi innych procesów związanych z budową/instalacją/konfiguracją aplikacji i środowisk. Wszystkie wymienione powyżej wymagania powodują, że narzędziom go wspierającym stawiane są bardzo duże wymagania, jeśli chodzi o możliwości integrowania systemów i ogólną elastyczność. Tego typu system, gdy jest odpowiednio skonfigurowany, służy zwykle jako swego rodzaju “punkt wejścia” dla wykonywania różnych inicjowanych automatycznie bądź ręcznie operacji wykonywanych w trakcie normalnej pracy projektowej.

Istnieje wiele komercyjnych, jak i darmowych rozwiązań tego typu: często nazywa się je “platformami CI”. Można tu wymienić choćby Bamboo (rozwiązanie firmy Atlassian) czy TeamCity (rozwiązanie firmy JetBrains). Jednak najbardziej rozpowszechnionym rozwiązaniem jest obecnie Jenkins będący oprogramowaniem open source.

Jak znaczna część platform CI, tak i Jenkins implementuje paradygmat build jako kod (ang. build as a code), który oznacza, że całość procesu ciągłej integracji (i innych procesów zaimplementowanych w narzędziu) definiuje się przygotowując odpowiedni program w jakimś języku specjalizowanym. Kategoria takich języków często oznaczana jest zbiorczo jako DSL (ang. domain specific language), w celu wyróżnienia ich od języków ogólnego przeznaczenia. Język DSL, którego używa Jenkins jest oparty o Groovy, który z kolei można określić jako “język skryptowy oparty o Java”.

Jednym z najważniejszych kryteriów użyteczności platform CI są ich możliwości integrowania różnych narzędzi – zarówno zewnętrznych w stosunku do samej platformy, jak i wykorzystywanych wewnątrz niej do pracy z określonymi językami programowania, bibliotekami czy całymi narzędziami. Zwykle tego typu rozszerzenia udostępniane są na platformie w postaci wtyczek (ang. plugin). Jenkins posiada obecnie (stan na maj 2021 roku) centralne repozytorium zawierające ponad 1800 wtyczek (zobacz Search Results | Jenkins plugin), w znacznej części tworzonych i udostępnianych liczną społeczność. W zasadzie można tam znaleźć wszystko, co jest potrzebne w standardowym projekcie realizowanym we jakiejkolwiek z rozpowszechnionych technologii.

Drugą z pożądanych cech platform są możliwości ich skalowania poziomego [skalowanie poziome to zwiększanie wydajności rozwiązania poprzez dodawanie nowych węzłów do wykorzystywanej infrastruktury. W przeciwieństwie do skalowania pionowego – czyli podnoszeniu wydajności węzłów (np. poprzez przydzielanie im dodatkowych zasobów).].

Sytuacja, gdy należy podnieść ogólną wydajność rozwiązania procesów CI i podobnych jest bardzo częsta. Kiedy? Na przykład gdy rozwiązanie rośnie. Wraz z rozrastaniem się projektu wzrastają również wymagania dot. ilości równoległych procesów budowy, czy ilości obsługiwanych środowisk. Dodatkowo, często istnieje konieczność wykorzystywania np. różnych systemów operacyjnych w różnych procesach zaimplementowanych na platformie CI.

Wszystkie rozpowszechnione platformy (w tym Jenkins) posiadają możliwość skalowania poziomego poprzez dodawanie centralnie zarządzanych węzłów. W Jenkinsie węzły mogą zostać stworzone na w zasadzie każdym rodzaju systemu operacyjnego, na którym możliwe jest uruchomienie maszyny wirtualnej Java. Oczywiście mogą być również tworzone jako kontenery. Zarówno w przypadkach kontenerów, jak i maszyn (zwykle wirtualnych) węzły Jenkins mogą funkcjonować jako rozwiązania chmurowe.

Ze względu na swój krótki cykl rozwojowy (cotygodniowe wydawanie nowych wersji), Jenkins jest rozwiązaniem podlegającym relatywnie szybkim zmianom. Ma to zarówno zalety, jak i określone konsekwencje. Najważniejszą z konsekwencji jest konieczność korzystania z kanału wersji stabilnych (aktualizowanych co około 12 tygodni i posiadających tzw. LTS – ang. long term support), jeśli wykorzystywane środowisko ma charakteryzować się wysoką niezawodnością i być wolne od błędów.

Testowanie

Szybkie i niezawodne testowanie automatyczne jest drugim z filarów procesu ciągłej integracji. DevOps kładzie szczególny nacisk na automatyzację tego procesu, bo rozwiązuje ona następujące problemy pojawiające się w przypadku manualnej realizacji testów przez przeznaczony do tego dział zapewnienia jakości (ang. quality assurance):

  • Koszt wykonywania testów manualnych (liczony czasem, a zatem i pieniędzmi na nie przeznaczonymi) rośnie wraz z wielkością aplikacji. Zwykle ten wzrost nie jest liniowy, bo złożoność aplikacji mierzona ilością związków między ich elementami rośnie zwykle w sposób bardziej zbliżony do wykładniczego i często tak też rośnie rozmiar i złożoność testów.
  • Z samej swojej natury testy manualne prawie nigdy nie mogą być wykonywane na tyle często, aby dostarczać informacji o jakości każdej zmiany wprowadzonej do kodu aplikacji i każdej zbudowanej przez platformę CI wersji. Zaburza to związek pomiędzy zmianami w aplikacji, a wykrytymi w niej błędami. W skrajnych przypadkach, gdy dla bardzo dużej aplikacji testy trwają wiele dni, zależność ta jest prawie zupełnie tracona. Powoduje to konieczność każdorazowego przeprowadzania “śledztwa” dotyczącego konkretnej przyczyny błędu. W przypadkach gdy trudno jednoznacznie wskazać zmiany, które są przyczyną błędu, może dochodzić np. do opisanego już wcześniej zjawiska “ping-ponga”. W sytuacji rzadko wykonywanych testów manualnych nie bez znaczenia jest również fakt, że poprzez swoją długotrwałość opóźniają przekazywanie programistom informacji zwrotnej o jakości ich kodu, tym samym spowalniając proces uczenia się na błędach.
  • Oczywistą wadą testów manualnych jest również ich mniejsza wiarygodność niż testów automatycznych. Mimo zastosowania wielu narzędzi wspomagających (choćby sformalizowanych scenariuszy testowych), z samej swojej natury czynności manualne są bardziej podatne na pomyłki niż czynności wykonywane przez automat.

Istnieje wiele kryteriów podziału testów, natomiast z punktu widzenia rekomendacji dawanych przez metodykę DevOps należy rozważyć ich dwie charakterystyczne grupy: testy jednostkowe i testy funkcjonalne. 

  • Testy jednostkowe – tworzone przez programistów w celu testowania pojedynczych metod, funkcji, czy całych klas. W większości sytuacji są bezstanowe – celem jest sprawdzanie, że testowany przez nie fagment kodu działa poprawnie. Jednym z celów realizacji procesu ciągłej integracji jest to, żeby wykonywanie testów jednostkowych i raportowanie ich wyników było procesem automatycznym i związanym z konkretnymi zmianami. 

Bardzo ważną wskaźnikiem pokazującym jakość tworzonego kodu jest miara stopnia pokrycia kodu testami jednostkowymi. Zwykle wyliczana dla metod, klas czy nawet rozgałęzień w kodzie i później jako obliczona wg. określonego algorytmu wartość podawana później w procentach. Często stosowaną metodą zapewnienia jakości jest stosowanie określonego minimalnego stopnia pokrycia nowo tworzonego kodu testami jednostkowymi. Nierzadką praktyką jest nawet uniemożliwienie programistom włączania (ang. merging) zmian do gałęzi integracyjnej kodu w sytuacji, gdy wskaźnik pokrycia nowego kodu testami nie przekracza pewnej minimalnej wartości.

  • Testy funkcjonalne – sprawdzanie aplikacji na poziomie udostępnianego przez nią interfejsu. Oczywiście mogą być zarówno manualne (nazywane powszechnie “klikaniem w aplikację”) albo automatycznie z użyciem specjalizowanych narzędzi. Idealnym rozwiązaniem przybliżającym projekt do rekomendowanych przez DevOps praktyk jest wykonywanie automatycznych testów funkcjonalnych każdorazowo w ramach działania procesu ciągłego dostarczania (po zainstalowaniu aplikacji na dedykowanym środowisku). Taki cel jest jednak często trudny do osiągnięcia ze względu na dwa czynniki:
    • Wysoki koszt związany z utrzymywaniem aktualności testów funkcjonalnych w stosunku do wytwarzanej aplikacji.
    • Czas wykonania takich testów – mierzony nawet w godzinach.

W praktyce w przypadku automatycznych testów funkcjonalnych często stosuje się dwa pośrednie rozwiązania: pierwsze to okresowe, niezależne od ciągłej integracji uruchamianie tych testów (np. w nocy). Drugie to manualne uruchomienie testów na wybranym środowisku z zainstalowanymi konkretną wersją aplikacji w celu np. przeprowadzania jej testów regresyjnych.

Funkcjonują również inne kryteria podziału testów – np. na cel ich przeprowadzania. Pojawiają się wtedy takie typy testów jak: testy regresyjne, testy wydajnościowe, czy testy wymagań niefunkcjonalnych. Omówienie tych tematów w kontekście DevOps dalece wykracza poza zakres tego artykułu.

Istnieje mnóstwo różnych narzędzi wspierających wykonywanie testów i gromadzenie oraz udostępnianie ich rezultatów. Wybór narzędzia zależy głównie od tego jaki typ aplikacji podlega testom i jaki rodzaj testów jest wykonywany. Z narzędzi dla testów funkcjonalnych aplikacji pracujących w oparciu o przeglądarki warto tutaj wymienić bardzo popularne Selenium – darmowe rozwiązanie pozwalające zarówno rejestrować ręcznie wykonywane czynności w celu późniejszego automatycznego ich odtwarzania, jak i tworzyć scenariusze testów w postaci kodu. Innym wartym wspomnienia narzędziem jest SonarQube – przedstawiciel narzędzi do wyliczania, gromadzenia i prezentowania danych o jakości kodu. 

Dane o wszelkiego rodzaju testach (np. ich wyniki i związki z tworzonym kodem) są dla takich narzędzi jednym z ważnych typów danych na podstawie których określana jest ta jakość.

Środek strumienia wartości technologii

Umowny środek strumienia wartości technologii wiąże się z przygotowaniem dwóch kluczowych produktów projektu jakimi są zwykle wersja produkowanej aplikacji oraz środowisko w jaki ma ona działać.

Pakowanie i wydawanie nowych wersji

Dwa wymienione w tytule procesy są często łączone ze względu na ich bliski związek – drugi nie istnieje bez pierwszego, ale w praktyce zdarza się również, że pierwszy zawsze pociąga za sobą drugi. Przez “pakowanie” rozumiemy tutaj przygotowanie nowej dystrybucji aplikacji i umieszczenie jej w miejscu wybranym do jej przechowywania – tzw. repozytorium artefaktów (ang. artifact repository). Taka operacja nie zawsze wiąże się z procesem przygotowania nowej wersji  (ang. release process), bo zdarza się że np. proces ciągłej integracji nie generuje nowych wersji aplikacji a jedynie umieszcza zbudowany artefakt w repozytorium – np. w strumieniu zmian pod znacznikiem ‘LATEST’ albo ‘SNAPSHOT’. 

Równie często praktykowane jest, że proces ciągłej integracji wcale nie produkuje jakiejkolwiek dystrybucji aplikacji przeznaczonej do przechowywania – w takich sytuacjach procesy pakowania i wydawania nowych wersji stanowią jedną całość.

Systemy repozytoriów artefaktów wspierające proces pakowania i udostępniania dystrybucji binarnych aplikacji (lub kontenerów je zawierających) są o tyle ważne dla całości działań w ramach DevOps, że dane w nich zawarte stanowią nie tylko źródło różnych wersji aplikacji w postaciach gotowych do użycia (lub wręcz archiwum wersji użytych, gdy dla danego artefaktu nastąpił również proces wydania nowej wersji) ale również źródło informacji o sposobie powstania tych wersji i miejscach ich wykorzystania. Dzieje się tak dzięki metadanym przechowywanych łącznie każdym artefaktem. Dzięki temu repozytoria artefaktów są cennym elementem wspierającym działania w ramach drugiej drogi DevOps.

Repozytoria artefaktów mogą funkcjonować zarówno jako samodzielne oprogramowanie takie jak np. JFrog Artifactory, ale są również częściami rozwiązań kontenerowych i orkiestacyjnych takich jak Docker i Kubernetes, czy wręcz PaaS – jak OpenShift.

Wydawanie nowych wersji jest natomiast częścią większego procesu – jest nim zarządzanie zmianą. Z punktu widzenia technicznego, jego podstawą jest zwykle albo wykorzystanie binarnej dystrybucji aplikacji już istniejącej w repozytorium artefaktów, albo przygotowanie nowego przeprowadzając na potrzeby tego wydania wszystkie wcześniejsze procesy począwszy od budowy.

Z drugiej strony, sam proces wydania nowej wersji nie jest ostatnim etapem procesu zarządzania zmianą (nawet w wąskim, “technicznym” znaczeniu tego terminu). W przypadku spełnienia zdefiniowanych kryteriów jakościowych i po podjęciu takiej decyzji, wersja podlega zwykle procesowi instalacji na środowisku wykonawczym – który to proces jest opisany dalej.

W związku z rozległością tematu i jego silną zależnością od technologii i specyfiki organizacji, omówione zostaną tylko ogólne zasady podejścia do tematu rekomendowane przez DevOps.

Zapraszamy do dyskusji

Patronujemy

 
 
More Stories
akademia it xtb
Ta firma od zawsze zatrudnia juniorów. Przejdź Akademię IT i znajdź pracę w XTB