Procesy CI/CD – czym są ciągła integracja i ciągłe dostarczanie?

Procesy CI/CD automatyzują drogę zmiany w kodzie od repozytorium przez budowanie i testowanie aż do przygotowania lub wdrożenia nowej wersji aplikacji. CI oznacza Continuous Integration, czyli ciągłą integrację. CD może oznaczać Continuous Delivery – ciągłe dostarczanie – albo Continuous Deployment, czyli ciągłe wdrażanie.

CI/CD nie jest metodą zarządzania projektem. To zestaw praktyk związanych z wytwarzaniem i dostarczaniem oprogramowania, szczególnie istotnych w DevOps. Ich celem jest skrócenie pętli informacji zwrotnej: po wprowadzeniu niewielkiej zmiany zespół powinien szybko dowiedzieć się, czy kod można zbudować, czy przechodzi testy i czy nadaje się do bezpiecznego wydania.

Microsoft opisuje CI/CD jako kilka powiązanych procesów: ciągłą integrację, ciągłe dostarczanie i ciągłe wdrażanie. Różnica między nimi dotyczy przede wszystkim tego, jak daleko automatycznie przemieszcza się zaakceptowana zmiana.

Co to jest CI, czyli ciągła integracja?

CI (Continuous Integration) to praktyka częstego integrowania niewielkich zmian kodu ze współdzielonym repozytorium oraz automatycznego sprawdzania tych zmian poprzez budowanie i testy.

Typowy proces wygląda następująco:

zmiana kodu → commit / pull request → automatyczny build → testy → informacja zwrotna

Jeżeli test nie przejdzie lub aplikacji nie da się poprawnie zbudować, zespół otrzymuje informację zanim problem zostanie połączony z dużą liczbą kolejnych zmian.

GitHub definiuje Continuous Integration właśnie jako praktykę częstego umieszczania kodu we wspólnym repozytorium. Częstsze i mniejsze zmiany ułatwiają wcześniejsze wykrywanie błędów oraz ograniczają zakres kodu, który trzeba analizować w przypadku awarii testu.

Co może sprawdzać proces CI?

Samo uruchomienie kompilacji to dopiero początek. Pipeline CI może wykonywać między innymi:

  • instalację zależności,
  • kompilację aplikacji,
  • linting i kontrolę formatowania,
  • analizę statyczną kodu,
  • testy jednostkowe,
  • testy integracyjne,
  • testy bezpieczeństwa,
  • sprawdzanie pokrycia testami,
  • budowanie obrazu kontenera,
  • przygotowanie artefaktu do dalszego wdrożenia.

Zakres zależy od technologii i ryzyka związanego z aplikacją.

Celem CI nie jest automatyzowanie wszystkiego, co technicznie możliwe. Pipeline powinien możliwie szybko odpowiadać na pytanie: czy tę zmianę można bezpiecznie integrować z pozostałym kodem?

Jeżeli podstawowe testy trwają godzinę, informacja zwrotna dociera zbyt późno. Warto wtedy przeanalizować, które kontrole powinny działać natychmiast, które można uruchamiać równolegle, a które należą do dalszych etapów procesu.

Co to jest CD?

Skrót CD bywa używany w dwóch znaczeniach:

  • Continuous Delivery – ciągłe dostarczanie,
  • Continuous Deployment – ciągłe wdrażanie.

Nie są to pojęcia równoważne.

Continuous Delivery – ciągłe dostarczanie

W Continuous Delivery zmiana, która przeszła proces integracji, jest automatycznie budowana, testowana i przygotowywana tak, aby mogła zostać wdrożona na produkcję.

Produkcja może jednak nadal wymagać świadomej decyzji człowieka.

Przykładowo:

commit → build → testy → staging → testy → akceptacja → produkcja

Najważniejsze jest to, że ręczna akceptacja nie oznacza ręcznego wykonywania całego wdrożenia. Po zatwierdzeniu pipeline może przeprowadzić techniczne kroki automatycznie.

Microsoft wskazuje, że w ciągłym dostarczaniu zmiany mogą być publikowane do środowiska zbliżonego do produkcyjnego, podczas gdy samo wdrożenie produkcyjne może nadal wymagać ręcznego zatwierdzenia.

Continuous Deployment – ciągłe wdrażanie

Continuous Deployment idzie krok dalej.

Zmiana, która pomyślnie przejdzie wszystkie zdefiniowane etapy pipeline’u, może zostać automatycznie wdrożona na produkcję bez ręcznej decyzji przed każdym wydaniem.

Schemat może wtedy wyglądać tak:

commit → build → testy → kontrole jakości → staging → testy → automatyczne wdrożenie produkcyjne

Wymaga to wysokiego poziomu dojrzałości automatyzacji, testów, monitoringu i procedur ograniczających skutki nieudanego deploymentu.

CI vs Continuous Delivery vs Continuous Deployment

ObszarContinuous IntegrationContinuous DeliveryContinuous Deployment
Główny celCzęsto integrować i weryfikować kodUtrzymywać oprogramowanie w stanie gotowym do wydaniaAutomatycznie publikować zaakceptowane zmiany
Automatyczny buildTakTakTak
Automatyczne testyTakTakTak
Przygotowanie wersji do wdrożeniaMoże występowaćTakTak
Wdrożenie na środowiska testoweZależnie od pipeline’uZwykle takTak
ProdukcjaPoza podstawowym zakresem CIMoże wymagać ręcznej akceptacjiAutomatyczna po spełnieniu warunków
Najważniejszy efektSzybki feedback o jakości zmianyKażda poprawna wersja może zostać wydanaKażda poprawna wersja może być od razu wydawana

To rozróżnienie jest istotne, ponieważ automatyczne wdrożenie na produkcję nie jest warunkiem stosowania CI/CD.

Firma działająca w sektorze regulowanym może mieć bardzo zaawansowany pipeline CI/CD i nadal wymagać kontrolowanej akceptacji przed wydaniem produkcyjnym.

Jak działa pipeline CI/CD?

Pipeline CI/CD to zautomatyzowany przepływ, przez który przechodzi zmiana oprogramowania.

Nie istnieje jeden uniwersalny pipeline. Prosta aplikacja może potrzebować kilku etapów, natomiast system finansowy lub platforma z wieloma mikrousługami może wykorzystywać znacznie więcej kontroli.

Typowy proces może wyglądać następująco:

kod → walidacja → build → testy → artefakt → staging → dalsze testy → release → production → monitoring

1. Zmiana trafia do repozytorium

Proces rozpoczyna się od systemu kontroli wersji, zwykle Git.

Zmiana może uruchomić pipeline po:

  • pushu do określonej gałęzi,
  • utworzeniu pull requesta lub merge requesta,
  • scaleniu do głównej gałęzi,
  • utworzeniu tagu,
  • ręcznym wywołaniu,
  • określonym harmonogramie.

GitHub Actions może uruchamiać workflow m.in. po zmianach w repozytorium, według harmonogramu lub po zdarzeniu zewnętrznym. GitLab pozwala konfigurować pipeline’y m.in. dla pushy, merge requestów i harmonogramów.

2. Kod jest budowany

Pipeline pobiera odpowiednią wersję kodu i tworzy z niej artefakt możliwy do dalszego wykorzystania.

Może to być:

  • plik wykonywalny,
  • paczka aplikacji,
  • obraz Docker,
  • pakiet biblioteki,
  • aplikacja frontendowa,
  • inny artefakt zależny od technologii.

Dobrą praktyką jest promowanie tego samego zweryfikowanego artefaktu między środowiskami, zamiast tworzenia od podstaw innej wersji przed każdym deploymentem.

3. Uruchamiane są automatyczne testy

Na tym etapie pipeline sprawdza zmianę.

Nie wszystkie testy muszą działać w jednym momencie. Szybkie testy jednostkowe mogą zostać wykonane na początku, a bardziej kosztowne testy integracyjne, end-to-end czy wydajnościowe później.

Jeżeli testy nie przejdą, pipeline powinien się zatrzymać.

Automatyzacja ma zapobiec sytuacji, w której wiadomo, że wersja jest wadliwa, ale proces mimo to przesuwa ją w kierunku produkcji.

4. Powstaje wersja możliwa do wdrożenia

Po przejściu kontroli można utworzyć wersjonowany artefakt i umieścić go np. w registry lub repozytorium artefaktów.

Oddzielenie procesu budowania od deploymentu ułatwia później ustalenie, jaka dokładnie wersja została wdrożona na konkretne środowisko.

5. Aplikacja trafia na środowisko testowe

Kolejne etapy mogą obejmować development, QA, staging czy pre-production.

Na środowisku bliższym produkcji można wykonać dodatkowe kontrole, np.:

  • testy integracyjne,
  • testy end-to-end,
  • testy migracji,
  • skanowanie bezpieczeństwa,
  • smoke tests,
  • testy wydajnościowe,
  • testy kompatybilności.

Dopiero wtedy zmiana może zostać dopuszczona do wydania.

6. Następuje deployment

W Continuous Delivery przed produkcją można pozostawić kontrolowany approval.

Nie oznacza to rezygnacji z automatyzacji. GitHub Actions umożliwia np. zdefiniowanie środowiska produkcyjnego z regułami ochrony i wymaganym zatwierdzeniem przed uruchomieniem joba wdrożeniowego.

W Continuous Deployment taka bramka może nie występować, jeżeli wszystkie zdefiniowane warunki można zweryfikować automatycznie.

7. Po wdrożeniu proces się nie kończy

Sam zielony pipeline nie oznacza, że użytkownicy otrzymali poprawnie działający system.

Po deploymentcie warto obserwować między innymi:

  • błędy aplikacji,
  • dostępność,
  • latency,
  • wykorzystanie zasobów,
  • anomalie,
  • zachowanie kluczowych funkcji biznesowych.

Niektóre organizacje wykorzystują również automatyczne mechanizmy zatrzymania rollout’u lub rollbacku po wykryciu problemu.

CI/CD powinno obejmować informację zwrotną z produkcji, a nie kończyć się na komunikacie „deployment successful”.

Przykład procesu CI/CD w praktyce

Załóżmy, że zespół rozwija aplikację SaaS.

Programista zmienia sposób naliczania rabatu i otwiera pull request.

Pipeline automatycznie:

  1. sprawdza format i statyczną jakość kodu,
  2. uruchamia testy jednostkowe,
  3. buduje aplikację,
  4. wykonuje testy integracyjne,
  5. skanuje zależności,
  6. tworzy wersjonowany obraz kontenera.

Jeżeli wszystkie kontrole przejdą, pull request może zostać zaakceptowany.

Po scaleniu do głównej gałęzi ten sam artefakt trafia na staging, gdzie uruchamiane są dalsze testy.

Jeżeli organizacja stosuje Continuous Delivery, produkcyjne wdrożenie może czekać na zatwierdzenie.

Jeżeli stosuje Continuous Deployment, wersja może trafić na produkcję automatycznie.

Po wdrożeniu monitoring pozwala sprawdzić, czy nowa wersja nie zwiększyła liczby błędów.

Właśnie taki przepływ jest istotą procesów CI/CD: kolejne powtarzalne kontrole i operacje są wykonywane przez pipeline, a zespół koncentruje się na zmianie i jej rezultacie.

Jak CI/CD łączy się z DevOps?

CI/CD jest jedną z podstawowych praktyk technicznych wspierających DevOps.

DevOps nie oznacza jednak po prostu „mamy Jenkinsa” albo „wdrożyliśmy GitHub Actions”.

Microsoft opisuje DevOps jako połączenie ludzi, procesów i technologii pozwalające stale dostarczać wartość, a CI/CD jako jedną z praktyk stosowanych w całym cyklu życia aplikacji.

Relację można uprościć do:

  • DevOps → sposób współpracy i organizacji dostarczania oprogramowania
  • CI/CD → automatyzacja i standaryzacja przepływu zmian
  • Infrastructure as Code → automatyzacja infrastruktury
  • observability → informacja o zachowaniu systemu po wdrożeniu

Dopiero połączenie tych elementów pozwala skrócić drogę od zmiany kodu do działającego rozwiązania.

Jakie korzyści daje CI/CD?

Największa wartość nie polega na samym skróceniu czasu wykonania deploymentu.

Szybsza informacja zwrotna

Jeżeli błąd pojawia się w niewielkim commicie i pipeline wykrywa go po kilku minutach, zakres poszukiwania przyczyny jest mniejszy niż w przypadku integracji dużego zestawu zmian po kilku tygodniach.

Mniejsze partie zmian

CI zachęca do częstego integrowania mniejszych zmian.

DORA wskazuje zmniejszanie wielkości zmian jako jeden ze sposobów poprawy szybkości i stabilności dostarczania oprogramowania: mniejsze zmiany są łatwiejsze do zrozumienia, wdrożenia i naprawienia w przypadku problemu.

Powtarzalny proces wydania

Jeżeli deployment jest opisany w pipeline, nie trzeba za każdym razem odtwarzać procedury z dokumentacji lub pamięci administratora.

Proces może być wersjonowany razem z kodem. Jenkins rekomenduje np. przechowywanie definicji Pipeline w Jenkinsfile w kontroli wersji, co umożliwia review, audyt zmian i utrzymywanie jednego źródła konfiguracji procesu.

Mniejsza liczba ręcznych operacji

Automatyzacja kompilacji, testów, przygotowania artefaktów i deploymentu eliminuje powtarzalne czynności podatne na pomyłki.

Nie oznacza to całkowitego wyeliminowania decyzji człowieka. Dobra automatyzacja usuwa czynności mechaniczne, ale zachowuje kontrolę tam, gdzie jest ona uzasadniona ryzykiem.

Jakie narzędzia wykorzystuje się w CI/CD?

Narzędzie jest tylko wykonawcą procesu. Najpierw trzeba zaprojektować przepływ, a później wybrać technologię.

Do popularnych platform należą:

NarzędzieCharakterystyka
GitHub ActionsWorkflow CI/CD zintegrowane bezpośrednio z repozytoriami GitHub
GitLab CI/CDPipeline’y definiowane w .gitlab-ci.yml, zintegrowane z GitLab
JenkinsRozbudowany, rozszerzalny serwer automatyzacji z Pipeline as Code
Azure PipelinesPipeline’y CI/CD w ekosystemie Azure DevOps
Argo CDContinuous Delivery dla Kubernetes oparte na podejściu GitOps

GitHub Actions pozwala budować, testować i wdrażać kod w workflow uruchamianych przez zdarzenia w repozytorium.

GitLab CI/CD buduje pipeline’y z jobs i stages zdefiniowanych w pliku YAML, przy czym joby w jednym etapie mogą wykonywać się równolegle.

Jenkins oferuje Pipeline as Code za pomocą Jenkinsfile, który może być przechowywany i wersjonowany razem z kodem aplikacji.

Nie należy więc wybierać narzędzia na podstawie tego, które jest „najlepsze”. Ważniejsze są istniejące repozytoria, infrastruktura, kompetencje zespołu, wymagania dotyczące bezpieczeństwa oraz sposób wdrażania aplikacji.

Bezpieczeństwo w procesach CI/CD

Pipeline ma często dostęp do repozytorium, registry, infrastruktury chmurowej i środowiska produkcyjnego. Jest więc częścią powierzchni ataku.

Szczególnej kontroli wymagają:

  • sekrety i tokeny,
  • uprawnienia runnerów,
  • zależności pobierane podczas builda,
  • zewnętrzne akcje i pluginy,
  • dostęp do środowiska produkcyjnego,
  • artefakty i obrazy kontenerów,
  • możliwość zmiany definicji pipeline’u.

Sekrety nie powinny znajdować się bezpośrednio w kodzie ani konfiguracji zapisanej w repozytorium.

Warto również stosować zasadę least privilege: pipeline powinien posiadać tylko te uprawnienia, które są konieczne w konkretnym etapie.

GitHub umożliwia oddzielne sekrety dla środowisk oraz reguły ochrony, które muszą zostać spełnione, zanim job otrzyma dostęp do chronionego środowiska.

Bezpieczeństwo można też przesuwać wcześniej w procesie poprzez automatyczne skanowanie kodu, zależności, kontenerów i konfiguracji infrastruktury.

Najczęstsze błędy przy wdrażaniu CI/CD

Automatyzacja złego procesu

Jeżeli wydanie wymaga 20 ręcznych kroków, nie należy bezrefleksyjnie automatyzować wszystkich 20.

Najpierw trzeba ustalić:

  • które kontrole są potrzebne,
  • które się powtarzają,
  • które nie wnoszą wartości,
  • które można wykonywać równolegle,
  • gdzie proces najdłużej czeka.

Najpierw uporządkowanie procesu, później jego automatyzacja.

Pipeline, który trwa zbyt długo

Pipeline ma zapewniać szybką informację zwrotną.

Jeżeli każda niewielka zmiana uruchamia trzy godziny testów, programista często zacznie wykonywać kolejne zadanie, zanim otrzyma wynik.

Warto wtedy podzielić testy, wykonywać część równolegle i umieszczać na początku kontrole, które szybko wykrywają najczęstsze problemy.

Niestabilne testy

Flaky tests, które raz przechodzą, a raz nie bez rzeczywistej zmiany zachowania aplikacji, szybko niszczą zaufanie do pipeline’u.

Gdy zespół zaczyna rutynowo ponawiać czerwony build „bo pewnie test znowu się zepsuł”, automatyczna kontrola przestaje pełnić swoją funkcję.

Budowanie innego artefaktu dla każdego środowiska

Jeżeli staging przetestował jeden build, a produkcja otrzymuje nowy, nie ma pewności, że wdrażany jest dokładnie ten sam artefakt.

Bezpieczniejszym modelem jest build once, deploy many – ten sam wersjonowany artefakt jest promowany przez kolejne środowiska.

Brak informacji po deploymentcie

Pipeline może zakończyć się sukcesem technicznym, podczas gdy aplikacja przestaje poprawnie realizować krytyczną funkcję biznesową.

Dlatego deployment trzeba połączyć z monitoringiem i obserwowalnością.

Jak wdrożyć proces CI/CD bez nadmiernej komplikacji?

Nie warto zaczynać od projektowania kilkudziesięciu etapów pipeline’u.

Pierwszy krok to prześledzenie obecnego procesu od commita do produkcji i znalezienie czynności powtarzalnych, ręcznych oraz powodujących najwięcej opóźnień.

Następnie można rozwijać automatyzację etapami.

Etap 1: podstawowe CI

Na początek wystarczy:

commit → build → podstawowe testy

Zespół otrzymuje automatyczną odpowiedź na każdą istotną zmianę.

Etap 2: kontrola jakości

Pipeline można rozszerzyć o:

linting → analizę kodu → testy integracyjne → kontrole bezpieczeństwa

Etap 3: wersjonowany artefakt

Po przejściu kontroli powinna powstawać konkretna wersja aplikacji gotowa do dalszego wdrażania.

Etap 4: automatyczny staging

Następnie można zautomatyzować deployment na środowisko testowe i testy wykonywane po wdrożeniu.

Etap 5: kontrolowany production deployment

Gdy wcześniejsze etapy są stabilne, produkcja może zostać dołączona do pipeline’u.

To, czy zachowana zostanie ręczna akceptacja, czy organizacja przejdzie do Continuous Deployment, powinno wynikać z poziomu ryzyka i dojrzałości procesu.

Nie ma potrzeby przechodzenia do automatycznego deploymentu produkcyjnego tylko po to, aby móc powiedzieć, że organizacja „ma CI/CD”.

Jak mierzyć skuteczność procesu CI/CD?

Nie warto oceniać pipeline’u wyłącznie na podstawie liczby wykonanych buildów.

Znacznie ważniejsze jest to, jak szybko i bezpiecznie zmiany przechodzą od kodu do użytkownika.

DORA w aktualnym modelu wykorzystuje pięć metryk wydajności dostarczania oprogramowania:

  • change lead time – czas od commita do działania zmiany na produkcji,
  • deployment frequency – częstotliwość deploymentów,
  • failed deployment recovery time – czas potrzebny na odzyskanie sprawności po nieudanym wdrożeniu,
  • change fail rate – udział wdrożeń wymagających natychmiastowej interwencji,
  • deployment rework rate – udział nieplanowanych wdrożeń wykonywanych w reakcji na problem.

Nie trzeba od razu budować rozbudowanego systemu pomiarowego.

W pierwszej kolejności można sprawdzić:

ile trwa droga od zaakceptowanej zmiany do produkcji, gdzie pipeline najczęściej czeka i które etapy najczęściej zawodzą.

To pozwala znaleźć rzeczywiste wąskie gardło.

Jeżeli build trwa trzy minuty, ale zmiana czeka dwa dni na ręczne utworzenie środowiska testowego, optymalizowanie czasu kompilacji nie rozwiąże głównego problemu.

Dobry proces CI/CD skraca drogę od zmiany do informacji zwrotnej

Wdrożenie CI/CD warto zacząć nie od Jenkinsa, GitHub Actions czy GitLab CI/CD, ale od obecnego przepływu dostarczania oprogramowania.

Trzeba ustalić, gdzie wykonywane są ręczne czynności, gdzie kod czeka, które błędy są wykrywane zbyt późno i które elementy procesu można wykonywać automatycznie.

Dopiero wtedy można zaprojektować pipeline.

W podstawowym wariancie wystarczy częsta integracja kodu, automatyczny build i szybkie testy. W bardziej dojrzałym procesie ten sam przepływ może obsługiwać tworzenie artefaktów, środowiska testowe, kontrole bezpieczeństwa, akceptacje, deployment produkcyjny i monitoring.

Najważniejszym efektem CI/CD nie jest więc „więcej automatyzacji”. Jest nim krótszy, powtarzalny i kontrolowany proces prowadzący od niewielkiej zmiany w kodzie do działającego oprogramowania oraz informacji, czy ta zmiana działa poprawnie.

Podobne wpisy