Wróć do katalogu
Season 25 14 Odcinki 56 min 2026

GitLab CI/CD

Edycja 2026. Kompleksowy przewodnik po zrozumieniu i wykorzystaniu GitLab CI/CD do wdrażania oprogramowania, obejmujący wszystko od podstaw pliku .gitlab-ci.yml po zaawansowane koncepcje, takie jak Directed Acyclic Graphs i potoki typu multi-project.

CI/CD DevOps
GitLab CI/CD
Teraz odtwarzane
Click play to start
0:00
0:00
1
Paradygmat .gitlab-ci.yml
Poznaj podstawowe koncepcje GitLab CI/CD. Ten odcinek omawia plik .gitlab-ci.yml, architekturę stage i job oraz to, jak domyślnie działa wykonywanie sekwencyjne.
3m 39s
2
Runners i Executors
Dowiedz się więcej o GitLab Runners, silnikach wykonawczych stojących za Twoimi potokami CI/CD. Analizujemy różnicę między runnerami hostowanymi przez GitLab a self-managed, oraz jak executors definiują środowisko dla job.
3m 48s
3
Anatomia CI/CD Job
Zagłęb się w podstawowy element budulcowy potoków: job. Ten odcinek wyjaśnia scripts w job, domyślne słowa kluczowe (keywords) oraz sposób organizowania złożonych logów potoku.
4m 02s
4
Zmienne CI/CD i Secrets
Odkryj, jak zarządzać konfiguracją i wrażliwymi danymi w GitLab CI/CD za pomocą zmiennych. Poznaj różnice między zmiennymi predefiniowanymi, niestandardowymi zmiennymi z interfejsu użytkownika oraz zmiennymi typu file.
4m 15s
5
Artifacts a Caches
Zrozum kluczową różnicę między artifacts a caches w GitLab CI/CD. Dowiedz się, kiedy używać każdego z nich do przekazywania danych między stages lub przyspieszania wykonywania potoku.
4m 12s
6
Kontrolowanie wykonywania za pomocą Rules
Odkryj, jak dynamicznie kontrolować, kiedy jobs są dodawane do Twojego potoku za pomocą słowa kluczowego rules. Naucz się używać warunków, zmiennych i zmian w plikach, aby zoptymalizować wykonywanie.
3m 23s
7
Directed Acyclic Graphs z użyciem Needs
Uwolnij się od ściśle sekwencyjnych stages. Ten odcinek wyjaśnia, jak używać słowa kluczowego needs do tworzenia Directed Acyclic Graphs (DAGs) i drastycznie przyspieszyć wykonywanie potoku.
3m 58s
8
Merge Request Pipelines
Dowiedz się, jak skonfigurować potoki, które uruchamiają się tylko w kontekście merge request. Omawiamy źródła potoków (pipeline sources) oraz kwestie bezpieczeństwa przy obsłudze forków od społeczności.
3m 59s
9
Downstream Pipelines
Opanuj wyzwalacze potoków (pipeline triggers), aby orkiestrować złożone architektury. Ten odcinek analizuje różnice między potokami Parent-Child dla monorepo a potokami Multi-project dla mikrousług.
3m 55s
10
Environments i Deployments
Zapewnij widoczność swoich wdrożeń dzięki GitLab Environments. Dowiedz się, jak mapować jobs CI/CD do konkretnych celów, takich jak staging i produkcja, oraz śledzić, jaki kod znajduje się w danym miejscu.
3m 41s
11
Dynamic Environments i Review Apps
Uruchamiaj tymczasową infrastrukturę dla każdego pull request. Ten odcinek zagłębia się w dynamic environments, przechwytywanie wygenerowanych adresów URL oraz czyszczenie zasobów za pomocą jobs typu on_stop.
4m 22s
12
Konfiguracje DRY z użyciem Includes
Utrzymaj swoją konfigurację CI/CD w duchu DRY (Don't Repeat Yourself). Odkryj, jak używać słowa kluczowego include, aby zmodularyzować konfigurację potoku w wielu plikach i projektach.
4m 37s
13
CI/CD Components i Catalog
Poznaj nowoczesną ewolucję reużywalności potoków: CI/CD Components. Dowiedz się, jak tworzyć projekty komponentów, używać semantycznego wersjonowania i wykorzystywać GitLab CI/CD Catalog.
4m 08s
14
Compile-Time CI Expressions
Odblokuj ostateczny dynamizm potoków dzięki wyrażeniom konfiguracyjnym CI/CD. Dowiedz się, jak składnia compile-time ewaluuje inputs i matrices, zanim jobs w ogóle się wykonają.
4m 12s

Odcinki

1

Paradygmat .gitlab-ci.yml

3m 39s

Poznaj podstawowe koncepcje GitLab CI/CD. Ten odcinek omawia plik .gitlab-ci.yml, architekturę stage i job oraz to, jak domyślnie działa wykonywanie sekwencyjne.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 1 z 14. Wiele zespołów inżynierskich polega na chaotycznych, nieudokumentowanych procesach release'owych, które tak naprawdę rozumie tylko jedna osoba. Rzeczywista ścieżka na produkcję pozostaje niewidoczna, dopóki coś się nie zepsuje. Paradygmat dot gitlab dash c i dot yml zmienia to, przekształcając cały cykl życia builda i release'u w przejrzysty, sekwencyjny graf. GitLab CI/CD to wbudowany w GitLaba system continuous integration i continuous deployment. Jest on w pełni kontrolowany przez pojedynczy plik konfiguracyjny o nazwie dot gitlab dash c i dot yml. Umieszczasz ten plik w katalogu root repozytorium twojego projektu. Ponieważ jest on commitowany razem z kodem twojej aplikacji, twój proces deploymentu podlega kontroli wersji, jest audytowalny i dostępny dla każdego developera przeglądającego repozytorium. Kiedy zrobisz push commita zawierającego ten plik, GitLab natychmiast go wykrywa i uruchamia pipeline. Pipeline to architektura najwyższego poziomu twojego procesu CI/CD. Składa się z dwóch głównych komponentów: jobów i stage'y. Joby określają, co faktycznie ma się wydarzyć. Job zawiera konkretne polecenia shellowe lub skrypty potrzebne do wykonania zadania, takiego jak kompilacja kodu źródłowego, formatowanie tekstu czy przeniesienie plików na serwer. Stage określają, kiedy te joby są uruchamiane. Organizujesz joby w stage, aby kontrolować chronologiczny flow wykonywania. Weźmy pod uwagę standardowy pipeline z trzema stage'ami. Na samej górze pliku konfiguracyjnego YAML deklarujesz swoje stage w dokładnej kolejności, w jakiej mają się uruchomić: build, test i deploy. Poniżej tej listy definiujesz swoje poszczególne joby i mapujesz je do tych zdefiniowanych stage'y. Zaczynasz od napisania joba o nazwie build dash job i przypisujesz go do stage'a build. Jego skrypt mówi systemowi, żeby skompilował twoją aplikację. Następnie piszesz joba o nazwie test dash job, przypisujesz go do stage'a test i podajesz komendę do uruchomienia twojego test suite'a. Na koniec piszesz joba deploy dash prod, linkujesz go do stage'a deploy i przekazujesz mu instrukcje, aby zrobił push skompilowanej aplikacji na środowisko produkcyjne. I tu jest kluczowa sprawa. GitLab przetwarza te stage ściśle po kolei. Pipeline zaczyna się od stage'a build. System wykonuje twojego build joba. Jeśli ten job zakończy się sukcesem, pipeline automatycznie przechodzi do stage'a test i wykonuje test joba. Jeśli testy przejdą, idzie dalej do stage'a deploy. Ta ścisła kolejność działa jak ostateczny quality gate. Jeśli job wywali się w jakimkolwiek momencie — na przykład, jeśli unit test nie przejdzie podczas stage'a test — cały pipeline się zatrzymuje. Stage deploy nigdy się nie wykona, co oznacza, że zepsuty kod nie ma szans trafić na produkcję. Ponieważ ta logika jest jasno zadeklarowana w pliku YAML, UI GitLaba tłumaczy ją na wizualny graf pipeline'u. Każdy w twoim zespole może wyświetlić commit, spojrzeć na graf i natychmiast zrozumieć, gdzie dokładnie znajduje się kod w pipelinie, który stage zakończył się sukcesem i gdzie dokładnie wystąpił błąd. Główną siłą tego paradygmatu jest centralizacja. Definiując stage i joby w jednym pliku w roocie, twoja sekwencja deploymentu przestaje być tajemnicą, a staje się czytelnym, powtarzalnym procesem, który żyje dokładnie w tym samym miejscu, co twój kod. Jeśli chcesz wesprzeć nasz podcast, możesz wyszukać DevStoriesEU na Patreonie. To wszystko na dzisiaj. Dzięki za wysłuchanie i koduj dalej!
2

Runners i Executors

3m 48s

Dowiedz się więcej o GitLab Runners, silnikach wykonawczych stojących za Twoimi potokami CI/CD. Analizujemy różnicę między runnerami hostowanymi przez GitLab a self-managed, oraz jak executors definiują środowisko dla job.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 2 z 14. Spędzasz godziny pisząc idealny plik konfiguracji pipeline'u, robisz commita i czekasz. Ale nic się nie dzieje. Twój pipeline jest całkowicie bezużyteczny bez silnika obliczeniowego czekającego na przechwycenie tych instrukcji. Właśnie tutaj do gry wchodzą GitLab Runners i Executors. Powszechnie panuje błędne przekonanie, że aplikacja GitLab sama uruchamia twoje skrypty budujące. Tak nie jest. GitLab zarządza repozytorium i śledzi status twoich pipeline'ów, ale samo wykonanie po prostu deleguje. GitLab Runner to osobna aplikacja działająca jako agent. Ciągle odpytuje instancję GitLaba, sprawdzając, czy są jakieś oczekujące joby, do których obsługi jest uprawniony. Kiedy takiego znajdzie, pobiera payload joba, wykonuje polecenia i wysyła logi oraz wyniki z powrotem do GitLaba. Masz dwie główne opcje na pozyskanie tych agentów. Najprostsza droga to użycie runnerów hostowanych przez GitLaba. Są one zarządzane za ciebie w ramach GitLab SaaS i pokrywają popularne środowiska, takie jak Linux, macOS i Windows. Często jednak potrzebujesz niestandardowego setupu. Być może twój build wymaga specjalistycznego sprzętu, takiego jak konkretne GPU, albo potrzebuje dostępu do prywatnej sieci wewnętrznej. W takim przypadku używasz runnerów self-managed. Instalujesz aplikację runnera na własnej infrastrukturze. Możesz ustawić scope tych runnerów self-managed szeroko, na całą instancję GitLaba, współdzielić je między grupą powiązanych projektów, albo przypisać je na sztywno do jednego, konkretnego projektu. Kiedy runner podejmie joba, musi dokładnie wiedzieć, jak i gdzie uruchomić polecenia. To właśnie definiuje executor. Executor dyktuje konkretne środowisko uruchomieniowe dla danego joba. Dwa najpopularniejsze typy to shell executor i Docker executor. Shell executor jest bardzo prosty. Uruchamia joba bezpośrednio w systemie operacyjnym hosta, używając standardowego shella w terminalu, jak Bash czy PowerShell. Z tego powodu wszystkie zależności muszą być preinstalowane na tej maszynie hosta. Docker executor działa inaczej. Podnosi świeży, odizolowany kontener dla każdego pojedynczego joba, uruchamia w nim skrypty, a po wszystkim go ubija. To gwarantuje całkowicie czyste środowisko za każdym razem. Przejdźmy przez konkretny scenariusz, rejestrując lokalnie runnera self-managed dla projektu, używając shell executora. Najpierw wchodzisz w ustawienia swojego projektu w GitLabie i tworzysz nowego runnera. GitLab wygeneruje unikalny token autoryzacyjny. Następnie instalujesz aplikację GitLab Runner na swojej lokalnej maszynie. W swoim lokalnym terminalu odpalasz komendę register. Prompt poprosi cię o dwie główne informacje. Potrzebuje adresu URL twojej instancji GitLaba oraz tokena, który właśnie wygenerowałeś. Ten krok bezpiecznie łączy twoją lokalną maszynę z tym konkretnym projektem. Na koniec setup poprosi cię o wybranie executora. Wpisujesz shell. Od tego momentu, za każdym razem, gdy w tym projekcie na GitLabie ztriggeruje się job, twoja lokalna maszyna go pobierze i wykona polecenia bezpośrednio w swoim lokalnym środowisku terminalowym. Oto kluczowy wniosek. GitLab jest orkiestratorem, ale Runner i jego Executor tworzą faktyczną halę produkcyjną. Rozdzielając zarządzanie jobami od ich wykonywania, zyskujesz elastyczność uruchamiania pipeline'ów na wszystkim, od współdzielonego kontenera w chmurze po serwer bare-metal w zamkniętej piwnicy. Dzięki za wysłuchanie, miłego kodowania wszystkim!
3

Anatomia CI/CD Job

4m 02s

Zagłęb się w podstawowy element budulcowy potoków: job. Ten odcinek wyjaśnia scripts w job, domyślne słowa kluczowe (keywords) oraz sposób organizowania złożonych logów potoku.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 3 z 14. Masz pipeline z dwudziestoma jobami, a każdy z nich zaczyna się od odpalenia dokładnie tej samej komendy setupowej. Kiedy ten proces setupu się zmienia, masz dwadzieścia różnych miejsc do zaktualizowania, a pominięcie choćby jednego zepsuje twój build. Pozbycie się tych powtórzeń zaczyna się od zrozumienia anatomii joba CI/CD. Job to podstawowa jednostka wykonania w GitLab CI/CD. Jest definiowany przez nazwę i musi zawierać co najmniej jedną komendę do uruchomienia. Ten główny blok wykonania jest definiowany za pomocą słowa kluczowego script. Script reprezentuje tablicę komend wykonywanych sekwencyjnie przez runnera. Jeśli jedna komenda zakończy się błędem, job natychmiast się zatrzymuje i jest oznaczany jako failed. Joby rzadko działają w próżni. Często wymagają przygotowania środowiska przed uruchomieniem, a czasami potrzebują późniejszego cleanupu. Właśnie tutaj wkraczają słowa kluczowe before script i after script. Weźmy na przykład projekt w Ruby. Przed uruchomieniem testów lub odpaleniem lintera, musisz zainstalować swoje zależności. Umieszczasz swoją komendę bundle install wewnątrz bloku before script. Runner wykonuje ten before script jako pierwszy. Jeśli się powiedzie, uruchamia się główny script. Po zakończeniu głównego scriptu, wykonuje się after script. Oto kluczowa informacja. After script uruchamia się nawet, jeśli główny script zakończy się błędem. Dzięki temu jest to idealne miejsce na zamykanie połączeń sieciowych, usuwanie tymczasowych credentials lub czyszczenie testowych baz danych. Wpisywanie tej samej komendy bundle install w każdym pojedynczym testowym jobie szybko staje się nużące. Aby to naprawić, używasz słowa kluczowego default na najwyższym poziomie swojego pliku konfiguracyjnego. Każda konfiguracja zdefiniowana pod default jest automatycznie dziedziczona przez wszystkie joby w pipeline. Deklarujesz swój before script z bundle install tylko raz, wewnątrz bloku default. Teraz każdy job uruchamia go automatycznie. Jeśli jakiś konkretny job go nie potrzebuje, definiujesz pusty before script wewnątrz tego konkretnego joba. Ta lokalna definicja nadpisuje globalny default. Czasami potrzebujesz definicji joba w swoim pliku, ale nie chcesz, żeby faktycznie się uruchomił. Możesz pisać bazowy template, z którego będą dziedziczyć inne joby, albo możesz chcieć tymczasowo wyłączyć flaky test bez całkowitego usuwania kodu. Robisz to poprzez ukrycie joba. Po prostu dodaj kropkę na samym początku nazwy joba. Kiedy GitLab parsuje konfigurację pipeline'u, całkowicie ignoruje każdą nazwę joba zaczynającą się od kropki. Job nie pojawi się w interfejsie użytkownika i nie zostanie wykonany. W miarę jak twój pipeline rośnie, interfejs webowy może zostać zaśmiecony dziesiątkami pojedynczych jobów. Jeśli masz kilka blisko powiązanych jobów, możesz je wizualnie pogrupować na grafie pipeline'u. Osiągasz to, nadając jobom nazwy ze wspólnym prefiksem, po którym następuje ukośnik lub dwukropek. Na przykład, jeśli nazwiesz trzy oddzielne joby build slash ruby one, build slash ruby two i build slash ruby three, interfejs zwinie je w jedną rozwijaną grupę o nazwie build. Kliknięcie grupy rozwija ją, pokazując poszczególne joby wewnątrz. Nie zmienia to niczego w sposobie wykonywania jobów przez runnery, ale sprawia, że ogromny pipeline jest o wiele łatwiejszy do odczytania na pierwszy rzut oka. Dobrze ustrukturyzowany pipeline oddziela setup od wykonania, używa defaultów, aby wyeliminować zduplikowany kod, i opiera się na konwencjach nazewnictwa, aby interfejs wizualny skupiał się wyłącznie na tym, co ważne. To wszystko w tym odcinku. Dzięki za wysłuchanie i budujcie dalej!
4

Zmienne CI/CD i Secrets

4m 15s

Odkryj, jak zarządzać konfiguracją i wrażliwymi danymi w GitLab CI/CD za pomocą zmiennych. Poznaj różnice między zmiennymi predefiniowanymi, niestandardowymi zmiennymi z interfejsu użytkownika oraz zmiennymi typu file.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 4 z 14. Zahardcodowanie klucza API bezpośrednio w konfiguracji pipeline'u to absolutnie najszybszy sposób na skompromitowanie całego środowiska produkcyjnego. Potrzebujesz sposobu na dynamiczne przekazywanie konfiguracji i credentialsów do twoich jobów, bez ujawniania ich komukolwiek, kto może odczytać twoje repozytorium. Zmienne CI/CD i sekrety to mechanizmy, które za to odpowiadają. Za każdym razem, gdy GitLab runner pobiera joba, nie startuje od pustego stanu. GitLab automatycznie wstrzykuje predefiniowane zmienne do środowiska. Dają one twojemu skryptowi natychmiastowy kontekst. Masz dostęp do zmiennych takich jak CI commit branch, pipeline ID czy nazwa projektu. Nie definiujesz ich. Po prostu tam są, gotowe do użycia w twoich skryptach, żeby sterować logiką albo tagować build artifacts. Poza predefiniowanym kontekstem, będziesz musiał dostarczyć własne, customowe zmienne. Możesz je zdefiniować w dwóch miejscach: w pliku konfiguracyjnym YAML albo w UI GitLaba. Zasada wyboru miejsca ich umieszczenia jest prosta. Jeśli wartość jest bezpieczna do odczytu, jak flaga kompilatora czy URL serwera deweloperskiego, wrzuć ją do pliku YAML. Konfiguracja zostaje wtedy z kodem. Jeśli wartość jest wrażliwa, jak hasło do bazy danych, zdefiniuj ją w UI projektu w GitLabie. Umieszczając sekret w UI, musisz skonfigurować jego granice bezpieczeństwa. Ludzie często mylą maskowanie zmiennej z jej ochroną. To zupełnie różne koncepcje. Maskowanie zmiennej zapobiega pojawieniu się jej wartości w logach joba. Jeśli zamaskujesz hasło do bazy danych, a źle napisany skrypt spróbuje wyświetlić je w konsoli, GitLab przechwyci strumień wyjściowy. Zastępuje rzeczywisty tekst hasła stringiem gwiazdek, zanim log w ogóle zostanie zapisany. Maskowanie kontroluje widoczność w logach. I tu jest kluczowa sprawa. Maskowanie w żaden sposób nie powstrzyma developera przed napisaniem skryptu, który wyśle hasło na zewnętrzny serwer. I tu do gry wchodzi ochrona. Ochrona zmiennej ogranicza jej dostępność. Chroniona zmienna jest wstrzykiwana tylko do pipeline'ów, które odpalają się na protected branches lub protected tags. Jeśli ktoś otworzy merge request ze standardowego feature brancha, pipeline, który wyzwoli, po prostu nie będzie zawierał tej zmiennej. To zapobiega dostępowi niezaufanego kodu do produkcyjnych sekretów. Dodatkowo, dla wyjątkowo wrażliwych danych, możesz użyć ukrytych ustawień w UI. Po zapisaniu zmiennej, jej wartość jest ukrywana w interfejsie. Nawet maintainerzy projektu nie mogą później łatwo odzyskać surowego tekstu, co oznacza, że ktoś z dostępem nie może tak po prostu zescrapować strony ustawień, żeby ukraść wszystkie twoje tokeny. Teraz zastanów się, w jaki sposób zmienna trafia do twojej aplikacji. Większość zmiennych jest wstrzykiwana jako standardowe zmienne środowiskowe. Ale niektóre narzędzia nie chcą czytać zmiennych środowiskowych i upierają się przy czytaniu z fizycznego pliku. Na przykład AWS CLI często oczekuje sformatowanego pliku z credentialsami leżącego na dysku. Zamiast pisać skrypt w pipeline, który tworzy plik, wrzuca do niego tekst zmiennej, a potem próbuje go bezpiecznie usunąć, możesz użyć zmiennej typu File. Kiedy skonfigurujesz zmienną jako typ File w UI, runner automatycznie zajmie się logistyką. Kiedy job startuje, runner bierze wartość tekstową, bezpiecznie zapisuje ją w pliku tymczasowym na dysku runnera i ustawia zmienną środowiskową tak, żeby zawierała ścieżkę do pliku, a nie jego zawartość. Po prostu wskazujesz swojemu narzędziu AWS ścieżkę podaną w zmiennej. Kiedy job się kończy, runner automatycznie niszczy plik. Zabezpieczanie pipeline'u polega na minimalizowaniu ekspozycji na każdym kroku. Nie polegaj na maskowaniu logów, żeby chronić się przed złośliwym kodem, i nie twórz samodzielnie tymczasowych plików z credentialsami, skoro runner może bezpiecznie obsłużyć ich lifecycle. To wszystko w tym odcinku. Dzięki za wysłuchanie i koduj dalej!
5

Artifacts a Caches

4m 12s

Zrozum kluczową różnicę między artifacts a caches w GitLab CI/CD. Dowiedz się, kiedy używać każdego z nich do przekazywania danych między stages lub przyspieszania wykonywania potoku.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 5 z 14. Twój build job kończy się pomyślnie, ale twój deployment job w tajemniczy sposób wywala się z błędem file not found. Sprawdzasz runnera i okazuje się, że pliki na pewno zostały wygenerowane zaledwie kilka minut temu. Problem zazwyczaj sprowadza się do fundamentalnego niezrozumienia dwóch słów kluczowych: artifacts i cache. Te dwa pojęcia są często mylone, ponieważ oba wiążą się z zapisywaniem plików na runnerze, ale istnieją z zupełnie innych powodów. Słowo kluczowe cache definiuje listę plików i katalogów, których celem jest przyspieszenie twojego pipeline'u. Przechowuje pobrane zależności między różnymi uruchomieniami pipeline'u. Weźmy na przykład standardowy projekt w Node. Twój build job wymaga tysięcy pakietów w folderze node modules. Zamiast pobierać je z publicznego registry za każdym razem, gdy developer pushuje kod, konfigurujesz cache. Nadajesz mu klucz oparty na twoim pliku package lock i wskazujesz na katalog node modules. Podczas kolejnych uruchomień GitLab przywraca te pliki lokalnie. Oto kluczowa sprawa. Caching to wyłącznie optymalizacja. Jeśli cache zostanie wyczyszczony, wygaśnie lub nie uda się go rozpakować, twój job musi nadal działać i zakończyć się sukcesem, pobierając pakiety od zera. Brak cache'u oznacza po prostu wolniejszy pipeline, a nie zepsuty. Logika twojego joba nigdy nie powinna zależeć od obecności cache'u. Artifacts służą zupełnie innemu celowi architektonicznemu. Słowo kluczowe artifacts określa pliki i katalogi generowane przez job, które muszą zostać przekazane do kolejnych jobów w ramach tego samego uruchomienia pipeline'u. Nie są one optymalizacją. Stanowią wymóg strukturalny dla twojego flow CI. Wracając do projektu w Node, twój build job kompiluje kod źródłowy do końcowego katalogu wyjściowego o nazwie dist. Twój deployment job jest uruchamiany na późniejszym stage'u i potrzebuje dokładnie tego folderu dist, aby wrzucić go na serwer produkcyjny. Ponieważ joby są uruchamiane w odizolowanych środowiskach, deploy job nie może po prostu sięgnąć do workspace'u build joba. Wypełniasz tę lukę za pomocą artifacts. Definiujesz folder dist pod słowem kluczowym artifacts w swoim build jobie. Po pomyślnym zakończeniu joba, GitLab bierze te pliki, pakuje je i dołącza do pipeline'u. Kiedy startuje downstreamowy deployment job, GitLab automatycznie pobiera ten pakiet artifacts i rozpakowuje go do katalogu roboczego. Jeśli brakuje artifactu, downstreamowy job zakończy się błędem, ponieważ wymagane pliki dosłownie nie istnieją w workspace. W przeciwieństwie do cache'u, nie możesz po prostu pobrać artifactu z internetu, jeśli go brakuje. Zawiera on unikalny, pośredni stan twojego bieżącego uruchomienia pipeline'u. W poprawnie skonfigurowanym pliku YAML często używasz obu w tym samym build jobie. Ustawiasz cache tak, aby wskazywał na folder zależności, żeby zaoszczędzić czas. Ustawiasz artifacts tak, aby wskazywały na folder ze skompilowanym kodem wyjściowym, żeby przekazać dane dalej. Deployment job w dalszej części pipeline'u w ogóle nie potrzebuje cache'u. Wymaga jedynie zbudowanego kodu, który otrzymuje bezproblemowo, ponieważ artifacts są domyślnie pobierane na wszystkich kolejnych stage'ach. Konfigurując swój kolejny pipeline, pamiętaj o tej zasadzie. Używaj cache'u dla zewnętrznych zależności, które pobierasz, żeby zaoszczędzić czas, a artifacts dla wewnętrznych wyników builda, które musisz przekazać dalej, żeby ukończyć deployment. To wszystko na dziś. Dzięki za wysłuchanie — idź zbudować coś fajnego.
6

Kontrolowanie wykonywania za pomocą Rules

3m 23s

Odkryj, jak dynamicznie kontrolować, kiedy jobs są dodawane do Twojego potoku za pomocą słowa kluczowego rules. Naucz się używać warunków, zmiennych i zmian w plikach, aby zoptymalizować wykonywanie.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 6 z 14. Właśnie zacommitowałeś poprawkę literówki w pliku markdown i nagle Twój pipeline odpala dwudziestominutowy zestaw testów end-to-end. To ogromna strata zarówno compute minutes, jak i Twojej cierpliwości. Aby nie uruchamiać ciężkich jobów, gdy nie są potrzebne, możesz kontrolować ich wykonywanie za pomocą słowa kluczowego rules. Słowo kluczowe rules dokładnie określa, kiedy job jest dodawany do pipeline'u. Jeśli korzystasz z GitLaba od jakiegoś czasu, możesz pamiętać używanie only i except do filtrowania jobów. To słowa kluczowe typu legacy. Rules to ich nowoczesny, potężniejszy zamiennik. Pod spodem, rules przyjmuje listę warunków. GitLab sprawdza tę listę od góry do dołu. Gdy tylko znajdzie dopasowanie, przestaje szukać i dodaje joba lub go pomija, w zależności od tego, jak skonfigurowałeś daną regułę. Są trzy główne warunki, które możesz sprawdzić. Pierwszy to if. Warunek if sprawdza zmienne pipeline'u za pomocą prostego wyrażenia logicznego. Możesz powiedzieć deploy jobowi, żeby uruchomił się tylko wtedy, gdy branch commitu pasuje do default brancha. Jeśli ewaluacja zmiennej zwróci true, reguła pasuje. Drugi warunek sprawdza modyfikacje plików za pomocą słowa kluczowego changes. Sprawdza on, czy obecny push zmodyfikował jakiekolwiek pliki pasujące do określonej ścieżki lub wildcarda. To tutaj możesz zaoszczędzić realne pieniądze. Weźmy pod uwagę ciężkiego joba z linterem JavaScriptu. Nie chcesz, żeby ten linter zżerał cykle procesora, jeśli backend developer ruszył tylko pliki konfiguracyjne bazy danych. Dodajesz regułę używając changes i podajesz wildcard dla plików .js. Jeśli commit zawiera zmiany w pliku JavaScript, reguła pasuje i linter się uruchamia. Jeśli żadne pliki JavaScript nie zostały ruszone, job jest całkowicie wykluczony z pipeline'u. Trzeci warunek to exists. Zamiast sprawdzać zmienne lub ostatnie modyfikacje, exists po prostu sprawdza, czy określony plik jest w danym momencie obecny w repozytorium. Możesz mieć generyczny szablon pipeline'u używany przez wiele projektów. Możesz zdefiniować job budujący kontener z regułą exists wskazującą na Dockerfile. Jeśli projekt ma Dockerfile w swoim głównym katalogu, job się uruchamia. Jeśli nie, job jest całkowicie pomijany. Oto kluczowa informacja. Znalezienie dopasowania nie oznacza automatycznie uruchomienia joba. Kiedy reguła zwraca true, stosuje dodatkową instrukcję za pomocą atrybutu when. Domyślnie pasująca reguła zakłada, że job powinien zostać dodany do pipeline'u. Możesz jednak jawnie zdefiniować regułę z atrybutem when ustawionym na never. Jest to bardzo skuteczne do blocklistingu. Możesz umieścić na samej górze listy regułę, która mówi, że jeśli commit message zawiera słowo draft, ustaw when na never. Ponieważ reguły są sprawdzane od góry do dołu, ten job jest natychmiast ubijany, zanim zostaną sprawdzone jakiekolwiek inne warunki. Jeśli masz zapamiętać jedną rzecz o kontrolowaniu wykonywania, to to, że kolejność decyduje o wyniku. Umieść swoje reguły wykluczające na samej górze listy, ponieważ w momencie, gdy GitLab znajdzie warunek true, przestaje czytać dalej i blokuje decyzję. Chciałbym poświęcić chwilę, aby podziękować Ci za słuchanie — to bardzo nam pomaga. Miłego dnia!
7

Directed Acyclic Graphs z użyciem Needs

3m 58s

Uwolnij się od ściśle sekwencyjnych stages. Ten odcinek wyjaśnia, jak używać słowa kluczowego needs do tworzenia Directed Acyclic Graphs (DAGs) i drastycznie przyspieszyć wykonywanie potoku.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 7 z 14. Twój pipeline nie jest tak naprawdę wolny. Jest po prostu sztucznie blokowany. Prawdopodobnie masz szybkie joby, które czekają na wolne joby, niemające z nimi absolutnie nic wspólnego, tylko dlatego, że siedzą w tej samej kolumnie na ekranie. Aby to naprawić, porzuć sztywne kolumny i zbuduj skierowane grafy acykliczne z użyciem needs. Domyślnie standardowe pipeline'y wykonują się sekwencyjnie, stage po stage'u. Definiujesz stage, takie jak build, test i deploy. Każdy job w stage'u test musi się całkowicie zakończyć, zanim jakikolwiek job w stage'u deploy będzie mógł wystartować. Jeśli twój stage test ma pięć jobów, z czego cztery kończą się w dwie minuty, a jeden zajmuje dziesięć, cały stage deploy jest zablokowany aż do dziesiątej minuty. Bariera egzekucji między stage'ami jest absolutna. Słowo kluczowe needs przełamuje tę barierę. Pozwala ci zdefiniować jawne relacje między jobami, zmieniając twój pipeline ze ścisłej sekwencji w skierowany graf acykliczny. Kiedy używasz słowa kluczowego needs w definicji joba, mówisz systemowi dokładnie, które poprzednie joby muszą się zakończyć, zanim ten wystartuje. W momencie, gdy te konkretne zależności zakończą się sukcesem, twój job startuje. Przestaje czekać, aż reszta stage'a się zakończy. Weźmy pod uwagę monorepo zawierające zarówno frontend, jak i backend. Twoje joby build i test dla backendu są szybkie i zajmują około dwóch minut. Twój build frontendu jest ciężki i zajmuje dziesięć minut. W tradycyjnym pipeline'ie, stage deploy nie może wystartować, dopóki nie zakończą się testy zarówno frontendu, jak i backendu. Twój deploy backendu jest w zasadzie zakładnikiem builda frontendu. Oto kluczowa sprawa. Możesz dodać słowo kluczowe needs do swojego joba backend deploy i podać tylko job backend test jako jego zależność. Teraz logika egzekucji się zmienia. Job backend test kończy się w drugiej minucie. Job backend deploy widzi, że jego jawna zależność jest spełniona i startuje natychmiast. Całkowicie ignoruje fakt, że build frontendu będzie działał przez kolejne osiem minut. Stage nadal istnieją dla wizualnej organizacji w interfejsie użytkownika, ale rzeczywista kolejność wykonywania jest teraz dyktowana przez graf, który zbudowałeś. Aby to skonfigurować, dodajesz słowo kluczowe needs do joba i podajesz array z dokładnymi nazwami jobów. Jest tu też dodatkowa korzyść związana z transferem danych. Zazwyczaj job pobiera artifacty ze wszystkich zakończonych sukcesem jobów z poprzednich stage'y. Kiedy używasz needs, pobieranie artifactów staje się ukierunkowane. Twój job pobierze artifacty tylko z konkretnych jobów wymienionych w arrayu needs. Zapobiega to pobieraniu przez twój job backend deploy ogromnych, nieistotnych assetów frontendu, oszczędzając jeszcze więcej czasu podczas inicjalizacji joba. Jeśli potrzebujesz, aby job wystartował natychmiast po utworzeniu pipeline'u, omijając wszystkie opóźnienia stage'y, możesz przekazać pusty array do słowa kluczowego needs. To mówi systemowi, że job ma zero zależności, wymuszając jego egzekucję w zerowej sekundzie. Prawdziwą wartością skierowanego grafu acyklicznego jest decoupling niezależnych workflow w ramach jednego pipeline'u. Przestajesz organizować joby według tego, kiedy powinny się uruchomić, a zaczynasz organizować je wyłącznie według tego, jakich inputów potrzebują do egzekucji. Dzięki za wysłuchanie. Trzymajcie się wszyscy.
8

Merge Request Pipelines

3m 59s

Dowiedz się, jak skonfigurować potoki, które uruchamiają się tylko w kontekście merge request. Omawiamy źródła potoków (pipeline sources) oraz kwestie bezpieczeństwa przy obsłudze forków od społeczności.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 8 z 14. Utrzymujesz projekt open-source. Ktoś robi jego forka, ukrywa skrypt eksportujący zmienne środowiskowe w unit teście i tworzy contribution. Jeśli twój system automatycznie uruchomi ten kod na twoich prywatnych serwerach, twoje sekrety przepadną. Aby temu zapobiec, potrzebujesz ścisłej granicy między zwykłym pushem kodu a wykonaniem go w uprzywilejowanym środowisku. Tę granicę wyznaczają Merge Request Pipelines. Zazwyczaj GitLab uruchamia pipeline za każdym razem, gdy zrobisz push commita do dowolnego brancha. Merge request pipeline zachowuje się inaczej. To specyficzny typ pipeline'u skonfigurowany tak, aby działał na zawartości source brancha, ale tylko w kontekście otwartego merge requesta. Ten kontekst daje ci dostęp do konkretnych zmiennych środowiskowych związanych z samym mergem, takich jak nazwa target brancha czy identyfikator merge requesta. Mówisz jobowi, żeby uruchomił się jako merge request pipeline, używając sekcji rules w twoim pliku konfiguracyjnym. Piszesz regułę sprawdzającą zmienną pipeline source. Sprawdzasz, czy CI pipeline source ma dokładnie wartość merge request event, zapisaną z podkreślnikami między słowami. Kiedy zastosujesz tę regułę, job uruchomi się tylko wtedy, gdy merge request zostanie utworzony lub zaktualizowany. Bardzo często łączy się to z regułami, które zapobiegają uruchamianiu joba przy standardowych pushach do brancha. Jeśli ich nie rozdzielisz, zrobienie pusha commita do otwartego merge requesta uruchomi dwa pipeline'y w dokładnie tym samym czasie, robiące dokładnie to samo. To prowadzi nas do kwestii bezpieczeństwa związanych z zewnętrznymi kontrybucjami. Kiedy ktoś robi forka twojego repozytorium, tworzy całkowicie odizolowaną kopię. Jeśli otworzy merge request ze swojego forka z powrotem do twojego głównego projektu, każdy pipeline, który uruchamia się automatycznie, wykonuje się wewnątrz jego forka. Używa jego runnerów i jego zmiennych. Tak to zostało zaprojektowane. Sekrety twojego głównego projektu są bezpieczne, ponieważ kod kontrybutora nie ma dostępu do twojej infrastruktury. Ale ostatecznie musisz zweryfikować, czy jego kod przechodzi twój oficjalny zestaw testów, używając twoich własnych credentialsów do bazy danych i targetów deploymentu. GitLab pozwala na uruchamianie pipeline'ów dla tych merge requestów z forków wewnątrz głównego projektu, ale wymaga to celowego działania człowieka. Developer lub maintainer w głównym projekcie musi ręcznie ztriggerować wykonanie. W prawidłowym workflow, maintainer najpierw czyta przesłany kod z forka. Musi sprawdzić, czy nie ma tam niczego złośliwego, destrukcyjnego lub źle napisanego. Dopiero gdy maintainer ma absolutną pewność, że kod jest bezpieczny, klika przycisk, aby ztriggerować pipeline. Po uruchomieniu, ten zewnętrzny kod wykonuje się na runnerach głównego projektu i ma dostęp do sekretów głównego projektu. Ręczny trigger działa jak fizyczna brama bezpieczeństwa. To jest najważniejsza część. Merge request pipelines to nie tylko sposób na grupowanie jobów w interfejsie użytkownika, to fundamentalny mechanizm kontroli, który pozwala ci ewaluować zewnętrzny kod bez ślepego wystawiania twojej wewnętrznej infrastruktury. Jeśli chcesz pomóc nam utrzymać ten projekt przy życiu, możesz wesprzeć podcast, wyszukując DevStoriesEU na Patreonie. To wszystko w tym odcinku. Dzięki za słuchanie i kodujcie dalej!
9

Downstream Pipelines

3m 55s

Opanuj wyzwalacze potoków (pipeline triggers), aby orkiestrować złożone architektury. Ten odcinek analizuje różnice między potokami Parent-Child dla monorepo a potokami Multi-project dla mikrousług.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 9 z 14. Masz pojedynczy plik YAML z pięciuset jobami. Zmiana jednej linijki przypomina rozbrajanie bomby, a wykonanie zajmuje godzinę, bo wszystko działa w jednym, ogromnym bloku. Downstream pipelines rozwiązują ten problem, dzieląc ten monolit na modułowe, niezależne workflows. Downstream pipeline to po prostu dowolny pipeline GitLab CI/CD uruchamiany przez inny pipeline. Pipeline, który go uruchamia, nazywa się upstream pipeline. Zamiast odpalać każdego joba w jednej sekwencji, upstream pipeline pełni rolę koordynatora, delegując pracę do mniejszych, wyspecjalizowanych pipeline'ów. GitLab dzieli downstream pipelines na dwa konkretne typy w zależności od tego, gdzie się wykonują. Pierwszy typ to parent-child pipeline. Dzieje się to w całości w ramach tego samego projektu. Jeśli masz monorepo, konfiguracja parent-child jest dokładnie tym, czego potrzebujesz. Parent pipeline wykrywa zmiany i triggeruje tylko odpowiednią konfigurację child. Drugi typ to multi-project pipeline. Ma to miejsce, gdy pipeline w jednym repozytorium triggeruje pipeline w zupełnie innym projekcie GitLab. Używasz tego przy architekturach rozproszonych w wielu repozytoriach, na przykład do triggerowania projektu testów integracyjnych dopiero po tym, jak pipeline samodzielnego projektu API zakończy się sukcesem. Oba typy konfigurujesz za pomocą konkretnego słowa kluczowego dla joba, czyli trigger. Trigger job zasadniczo różni się od standardowego joba. Nigdy nie zawiera sekcji script. Nie wykonuje poleceń na runnerze. Jego jedynym celem jest wystartowanie downstream pipeline. W przypadku multi-project pipeline, przekazujesz do słowa kluczowego trigger ścieżkę do docelowego projektu. W przypadku parent-child pipeline, używasz słowa kluczowego trigger w połączeniu ze słowem kluczowym include, wskazując na inny plik YAML znajdujący się w tym samym repozytorium. Pomyśl o routującym parent pipeline, który zarządza trzema oddzielnymi mikroserwisami przechowywanymi w monorepo. Parent pipeline ocenia commit i triggeruje trzy równoległe child pipelines. Jeden obsługuje serwis użytkowników, drugi serwis płatności, a trzeci serwis magazynowy. Każdy child pipeline ma swoje własne stages, joby i rules. Wykonują się niezależnie. Domyślnie trigger job działa na zasadzie fire and forget. Upstream job startuje downstream pipeline i natychmiast kończy się sukcesem. Jeśli potrzebujesz, żeby upstream pipeline poczekał i odzwierciedlił status downstream pipeline, dodajesz parametr strategy depend do trigger joba. To wymusza na parent pipeline oczekiwanie, co oznacza, że błąd w child pipeline przebije się wyżej i oznaczy parent job jako failed. Oto kluczowa sprawa. Inżynierowie często konfigurują parent-child pipelines i od razu zakładają, że są zepsute, ponieważ child pipelines nie pojawiają się na głównej stronie indeksu pipelines. To celowy wybór projektowy. Główny indeks pokazuje tylko parent pipelines, żeby uniknąć bałaganu. Żeby zobaczyć child pipelines, musisz kliknąć w widok szczegółów parent pipeline. Są one zagnieżdżone pod konkretnym jobem, który je ztriggerował. Z kolei multi-project pipelines pojawiają się w indeksie pipelines swoich docelowych projektów, ponieważ są to top-level pipelines w tych repozytoriach. Przejście na downstream pipelines zmusza cię do traktowania konfiguracji CI/CD jak prawdziwej architektury oprogramowania, zastępując jeden kruchy skrypt oddzielnymi komponentami z odizolowanymi domenami awarii. To tyle na dzisiaj. Do usłyszenia następnym razem!
10

Environments i Deployments

3m 41s

Zapewnij widoczność swoich wdrożeń dzięki GitLab Environments. Dowiedz się, jak mapować jobs CI/CD do konkretnych celów, takich jak staging i produkcja, oraz śledzić, jaki kod znajduje się w danym miejscu.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 10 z 14. Jeśli twój zespół musi pytać na Slacku, kto właśnie zrobił pusha na staging, masz problem z widocznością w swoim workflow. Potrzebujesz pewnego, zautomatyzowanego sposobu, żeby w każdej sekundzie śledzić, jaki dokładnie kod i gdzie jest uruchomiony. I to jest dokładnie ten problem, który rozwiązują GitLab Environments i Deployments. W GitLabie environment to logiczna encja do śledzenia. GitLab nie prowizjonuje automatycznie twoich serwerów ani nie stawia infrastruktury chmurowej tylko dlatego, że utworzyłeś environment. Environment to po prostu etykieta. Mówi ona GitLabowi, że konkretny job w twoim pipeline odpowiada za wrzucenie kodu do określonego miejsca docelowego, takiego jak staging czy produkcja. Konfigurujesz to, dodając słowo kluczowe environment bezpośrednio w swoim deployment jobie. Podajesz statyczną nazwę dla miejsca docelowego. Na przykład, możesz utworzyć job o nazwie deploy to staging, a w jego obrębie ustawić nazwę environmentu na staging. Sekcja script twojego joba nadal wykonuje właściwą pracę. Uruchamia komendy, które kopiują pliki, aplikują konfiguracje lub restartują zdalne serwisy. Wyobraź sobie scenariusz, w którym deployujesz nowy release candidate. Mergujesz swój kod i uruchamia się pipeline. Buduje aplikację, odpala testy i dociera do joba deploymentowego na staging. Ponieważ dodałeś słowo kluczowe environment do tego joba, GitLab zmienia sposób, w jaki traktuje jego wykonanie. Uważnie monitoruje output joba. Kiedy twój skrypt deploymentowy się kończy, a job kończy się sukcesem, GitLab rejestruje formalny event deploymentowy dla environmentu staging. Oto kluczowa sprawa. Użycie tego jednego słowa kluczowego aktywuje cały zestaw funkcji do śledzenia deploymentów w interfejsie GitLaba. Jeśli przejdziesz do menu Operate na pasku bocznym i wybierzesz Environments, zobaczysz dashboard pokazujący w czasie rzeczywistym status twoich targetów deploymentowych. Dla twojego environmentu staging nie musisz już zgadywać, co jest uruchomione. Dashboard wyświetla dokładny hash commita, który jest obecnie aktywny, branch, z którego ten commit pochodzi, autora kodu oraz czas, jaki upłynął od zakończenia deploymentu. Tworzy to niezmienny, współdzielony zapis stanu serwera. Wszyscy w projekcie mają dokładnie taką samą widoczność, bez konieczności sprawdzania logów serwera czy pytania współpracowników. Kliknięcie w environment staging odkrywa pełną historię deploymentów. Ten historyczny zapis to coś, co umożliwia ręczne rollbacki bezpośrednio z interfejsu użytkownika. Jeśli nowy release candidate całkowicie zepsuje serwer stagingowy, naprawa nie wymaga pisania revert commita ani ręcznego budowania starszego pipeline'u. Otwierasz listę historii, identyfikujesz ostatni znany udany deployment i klikasz przycisk rollback obok niego. GitLab natychmiast ponownie uruchamia deployment job z tego starszego, stabilnego commita. Zastępuje zepsuty kod i szybko przywraca twój environment staging do działającego stanu. Używając słowa kluczowego environment, wypełniasz lukę między uruchamianiem skryptów a śledzeniem faktycznych deploymentów. Zamienia to odizolowany job w pipeline w przejrzysty, widoczny zapis tego, jaka wersja oprogramowania aktualnie żyje na twojej infrastrukturze. Chciałbym poświęcić chwilę, żeby podziękować ci za słuchanie – to bardzo nam pomaga. Miłego dnia!
11

Dynamic Environments i Review Apps

4m 22s

Uruchamiaj tymczasową infrastrukturę dla każdego pull request. Ten odcinek zagłębia się w dynamic environments, przechwytywanie wygenerowanych adresów URL oraz czyszczenie zasobów za pomocą jobs typu on_stop.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 11 z 14. Przekazanie product managerowi działającego, klikalnego adresu URL dla każdego feature brancha całkowicie eliminuje argument, że na twoim komputerze to działa. Ten workflow opiera się w całości na Dynamic Environments i Review Apps. Standardowe środowiska, takie jak staging czy produkcja, są statyczne. Definiujesz je raz i istnieją cały czas. Środowiska dynamiczne są tworzone w locie. Stawiasz je, żeby przetestować konkretny branch, używasz ich, a potem wyrzucasz. Kiedy używasz środowiska dynamicznego specjalnie do podglądu zmian w kodzie wewnątrz merge requesta, GitLab nazywa to Review App. Aby utworzyć środowisko dynamiczne, nie możesz zahardkodować jego nazwy w pliku konfiguracyjnym. Zamiast tego używasz zmiennych pipeline'u. Najważniejszą zmienną do tego celu jest CI commit ref slug. Zmienna ta bierze nazwę twojego brancha, zamienia ją na małe litery, usuwa znaki specjalne i ją skraca. Gwarantuje to, że masz bezpieczny dla DNS string, którego możesz użyć do nazwania zarówno swojego środowiska w GitLabie, jak i rzeczywistych zasobów infrastruktury. Definiując nazwę środowiska jako słowo review, po którym następuje slash i ta zmienna slug, GitLab automatycznie generuje oddzielne, śledzone środowisko dla każdego zpushowanego brancha. I tu jest kluczowa sprawa. Utworzenie rekordu środowiska w GitLabie to tylko połowa sukcesu. Musisz również przekierować recenzentów do faktycznie zdeployowanego kodu. Załóżmy, że stawiasz tymczasową instancję AWS Lambda dla swojego feature brancha. Kiedy twój skrypt do deployu się uruchamia, AWS generuje losowy adres URL dla tej nowej funkcji Lambda. Nie znasz tego adresu URL z góry. Potrzebujesz sposobu na przekazanie tego dynamicznie wygenerowanego adresu z powrotem do UI GitLaba, żeby recenzenci mogli w niego kliknąć. Rozwiązujesz ten problem za pomocą konkretnego typu artifactu o nazwie dotenv report. Wewnątrz twojego joba deploymentowego, po tym jak AWS sprovisionuje funkcję Lambda i zwróci endpoint, twój skrypt zapisuje ten adres URL do prostego pliku tekstowego sformatowanego jako para klucz-wartość. Konfigurujesz swojego joba tak, aby wyrzucił ten plik jako artifact typu dotenv report. GitLab odczytuje ten plik na końcu joba i wystawia tę zmienną. Następnie konfigurujesz parametr environment URL w definicji swojego pipeline'u, aby odczytał dokładnie tę zmienną. Dzięki temu połączeniu twój merge request będzie teraz wyświetlał przycisk View App, który kieruje użytkowników bezpośrednio do tego konkretnego endpointu AWS Lambda. Tymczasowa infrastruktura kosztuje. Zostawienie setek wiszących funkcji Lambda szybko wyczerpie twój budżet. Potrzebujesz zautomatyzowanego sposobu na ich sprzątanie. Ogarniasz to za pomocą keyworda on stop. W swoim jobie deploymentowym dodajesz property on stop i podajesz w nim dokładną nazwę innego joba w twoim pipeline'ie. Ten drugi job zawiera twój skrypt do teardownu infrastruktury. Łącząc je w ten sposób, GitLab przejmuje zarządzanie lifecyclem. Kiedy developer zmerguje feature brancha albo usunie brancha, GitLab automatycznie wykonuje ten teardown job. Infrastruktura jest natychmiast niszczona. Prawdziwą wartością Review Apps jest nie tylko podgląd kodu, ale automatyzacja całego lifecycle'u infrastruktury. Dynamicznie provisionujesz, płynnie łączysz i niezawodnie niszczysz tymczasowe środowiska, bez konieczności dotykania konsoli hostingowej przez jakiegokolwiek developera. To wszystko w tym odcinku. Dzięki za wysłuchanie i budujcie dalej!
12

Konfiguracje DRY z użyciem Includes

4m 37s

Utrzymaj swoją konfigurację CI/CD w duchu DRY (Don't Repeat Yourself). Odkryj, jak używać słowa kluczowego include, aby zmodularyzować konfigurację potoku w wielu plikach i projektach.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 12 z 14. Kopiowanie i wklejanie dokładnie tego samego skryptu do deployu do pięćdziesięciu różnych repozytoriów gwarantuje jedno: gdy ten skrypt nieuniknienie będzie wymagał zmiany, zapomnisz zaktualizować co najmniej jedno repozytorium. Rozwiązaniem jest pisanie konfiguracji DRY z użyciem słowa kluczowego include. W GitLab CI słowo kluczowe include pozwala podzielić konfigurację pipeline'u na wiele mniejszych plików, których możesz użyć ponownie. Zamiast utrzymywać jeden ogromny plik YAML, budujesz system modułowy. Kiedy pipeline się uruchamia, GitLab pauzuje, pobiera wszystkie dołączone pliki, merguje je ze sobą, a następnie przetwarza połączoną konfigurację jako całość. Istnieją trzy główne podklucze, których używasz do zaciągania tych zewnętrznych plików. Najprostszy to local. Używasz include local, aby zaciągnąć plik, który znajduje się w dokładnie tym samym repozytorium co twój główny plik pipeline'u. Służy to wyłącznie do organizacji pojedynczego, dużego projektu. Możesz wydzielić całą logikę testowania do pliku o nazwie test pipeline dot yml, umieścić logikę deploymentu w pliku deploy pipeline dot yml i zachować porządek w swoim rootowym pliku konfiguracyjnym, po prostu odwołując się do tych lokalnych ścieżek. Drugim podkluczem jest project i to właśnie tutaj modułowość pipeline'u skaluje się na całą organizację. Include project zaciąga plik YAML z zupełnie innego repozytorium hostowanego na tej samej instancji GitLaba. Określasz ścieżkę zewnętrznego projektu, wraz ze ścieżką pliku i opcjonalnie konkretny branch lub referencję do commita, które chcesz zaciągnąć. Wyobraź sobie zespół platformowy, który utrzymuje centralny pipeline do skanowania bezpieczeństwa. Zamiast pięćdziesięciu różnych zespołów od mikrousług, które piszą i utrzymują swoje własne joby bezpieczeństwa, zespół platformowy utrzymuje jeden autorytatywny szablon YAML w dedykowanym projekcie platformowym. Te pięćdziesiąt projektów mikrousług po prostu dodaje blok include project wskazujący na to centralne repozytorium. Kiedy zespół platformowy zaktualizuje wersję skanera lub podkręci reguły bezpieczeństwa w swoim szablonie, wszystkie pięćdziesiąt mikrousług automatycznie uruchomi zaktualizowane testy przy kolejnym wykonaniu pipeline'u. Żadne powtarzalne kopiowanie i wklejanie nie jest potrzebne. Trzeci podklucz to remote. Include remote przyjmuje pełny adres URL HTTPS i pobiera plik konfiguracyjny z dowolnego publicznego serwera WWW. Możesz tego użyć do zaciągnięcia definicji pipeline'ów dostarczonych przez vendora lub standardów społeczności open source. Jedynym ścisłym wymogiem jest to, że adres URL musi być publicznie dostępny przez standardowy request webowy bez autentykacji. Teraz zwróć uwagę na ten fragment. Często spotkasz się z sytuacją, w której dołączony plik definiuje joba, ale twój lokalny projekt musi go nieznacznie zmodyfikować. GitLab radzi sobie z tym poprzez swój mechanizm mergowania. Kiedy pliki są dołączane, GitLab wykonuje deep merge konfiguracji. Jeśli dołączony plik definiuje joba o nazwie run security scan, a twój główny plik również definiuje joba o nazwie run security scan, konfiguracja w twoim głównym pliku ma pierwszeństwo. Oznacza to, że nie musisz porzucać scentralizowanego szablonu tylko dlatego, że twój konkretny projekt wymaga drobnej modyfikacji. Możesz dołączyć szablon zespołu platformowego, a następnie lokalnie zdefiniować tylko joba run security scan ze zaktualizowaną zmienną lub dodatkowym customowym skryptem. Twoje lokalne nadpisania mają zastosowanie, podczas gdy reszta definicji joba pozostaje dokładnie taka, jak napisał ją zespół platformowy. Prawdziwa siła modułowości pipeline'u tkwi nie tylko w centralizacji kodu, ale w projektowaniu szablonów jako rozsądnych wartości domyślnych, które projekty downstreamowe mogą lokalnie nadpisywać bez psucia łańcucha dziedziczenia. To wszystko w tym odcinku. Dzięki za wysłuchanie i budujcie dalej!
13

CI/CD Components i Catalog

4m 08s

Poznaj nowoczesną ewolucję reużywalności potoków: CI/CD Components. Dowiedz się, jak tworzyć projekty komponentów, używać semantycznego wersjonowania i wykorzystywać GitLab CI/CD Catalog.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 13 z 14. Twój pipeline właśnie padł, bo ktoś zaktualizował współdzielony snippet YAML trzy repozytoria dalej. Nie miałeś żadnego ostrzeżenia, a teraz spędzasz godzinę na naprawianiu joba, którego nawet nie napisałeś. Czasy polegania na kruchych, niewersjonowanych snippetach YAML minęły bezpowrotnie. CI/CD Components i CI/CD Catalog rozwiązują ten problem, wprowadzając niezawodność package managera bezpośrednio do twoich pipeline'ów. Komponenty to reużywalne konfiguracje pipeline'ów o pojedynczym przeznaczeniu. Działają jako nowoczesna ewolucja starej metody include template. W przypadku starszych template'ów, w zasadzie importowałeś surowy YAML przez sieć. Jeśli plik upstream uległ zmianie, twój pipeline zmieniał się natychmiast, często z katastrofalnymi skutkami. Komponenty rozwiązują to, wymuszając ścisłe wersjonowanie. CI/CD Catalog służy jako scentralizowany rejestr, w którym twoja organizacja może publikować, odkrywać i udostępniać te wersjonowane komponenty. Żeby zbudować komponent, potrzebujesz repozytorium o bardzo konkretnej strukturze plików. Główna logika musi znajdować się w katalogu o nazwie templates. W tym katalogu możesz umieścić wiele plików YAML, z których każdy reprezentuje osobny komponent. W głównym katalogu repozytorium musisz też dodać plik readme dot md. Ten plik markdown to nie tylko grzeczna sugestia. Działa on jako oficjalna dokumentacja wyświetlana w Catalogu, szczegółowo opisująca, co robi komponent i jakich parametrów wymaga. Oto kluczowa sprawa. Komponenty są zbyt sztywne, żeby były użyteczne bez inputów. Inputy działają dokładnie tak samo jak argumenty funkcji dla twojej konfiguracji pipeline'u. Kiedy piszesz YAML komponentu, na samej górze deklarujesz blok, który definiuje akceptowane inputy. Określasz ich nazwy, wartości domyślne i to, czy są wymagane. Wyobraź sobie zespół platform engineeringu, który wdraża obowiązkowe skany bezpieczeństwa. Tworzą projekt komponentu o nazwie corporate-security. W katalogu templates piszą plik przeznaczony specjalnie do secret detection. Żeby zachować elastyczność, definiują jeden wymagany input o nazwie stage. Deweloperzy aplikacji w całej firmie nie muszą już samodzielnie pisać ani utrzymywać jobów do secret detection. Żeby użyć tego konkretnego komponentu do secret detection, deweloper używa składni include component w swojej konfiguracji pipeline'u. Podaje ścieżkę do komponentu na serwerze. Następnie dodaje symbol at, a po nim wersję semantyczną, na przykład jeden kropka zero kropka zero. To kluczowy krok. Przypięcie wersji semantycznej gwarantuje, że pipeline nigdy nie wywali się nieoczekiwanie, nawet jeśli zespół platformowy wyda mocno zmodyfikowaną wersję dwa kropka zero kropka zero jeszcze w tym samym tygodniu. Jeśli deweloper celowo chce być na bleeding edge, może dodać specjalny tag tylda latest zamiast numeru wersji, ale semantic versioning to bezpieczniejszy default. Tuż pod deklaracją include, deweloper przekazuje swoje zmienne, mapując input stage na dowolny stage pipeline'u, który pasuje do jego konkretnego projektu, na przykład test lub pre-build. Traktowanie logiki pipeline'u jako wersjonowanego oprogramowania zmienia sposób, w jaki zespoły skalują infrastrukturę. Prawdziwa siła komponentów to nie tylko reużywalność kodu, to absolutna gwarancja, że pipeline, który działa dzisiaj bez błędu, zadziała dokładnie tak samo za sześć miesięcy. Dzięki za wysłuchanie. Trzymajcie się wszyscy.
14

Compile-Time CI Expressions

4m 12s

Odblokuj ostateczny dynamizm potoków dzięki wyrażeniom konfiguracyjnym CI/CD. Dowiedz się, jak składnia compile-time ewaluuje inputs i matrices, zanim jobs w ogóle się wykonają.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. GitLab CI/CD, odcinek 14 z 14. Próbujesz zdefiniować nazwę stage'a dla joba przy użyciu standardowej zmiennej CI, pushujesz kod i natychmiast dostajesz syntax error. Pipeline odmawia uruchomienia. Problemem jest timing. Runner nie może zdefiniować struktury pipeline'u za pomocą zmiennych, które otrzymuje dopiero po tym, jak pipeline już wystartował. I tu właśnie wkraczają Compile-Time CI Expressions. Oto w czym rzecz. Standardowe zmienne runtime'owe, zapisywane z pojedynczym znakiem dolara, są ewaluowane przez shella, gdy job faktycznie się wykonuje. Zanim runner je zobaczy, cała architektura pipeline'u jest już zablokowana. Nie możesz dynamicznie zmienić nazwy stage'a, service'u ani wersji obrazu podczas egzekucji, ponieważ GitLab potrzebuje tych informacji z góry, żeby zbudować graf pipeline'u. Compile-time expressions rozwiązują ten problem, ewaluując logikę dokładnie w momencie, gdy GitLab parsuje twoją konfigurację YAML, na długo przed przypisaniem jakiegokolwiek runnera. Składnia to znak dolara, po którym następują podwójne nawiasy kwadratowe. Wewnątrz tych nawiasów wpisujesz wyrażenie, które ewaluuje się do wartości przed utworzeniem pipeline'u. Te wyrażenia pobierają dane z określonych kontekstów. Kontekst to w zasadzie ograniczony zestaw danych dostępnych podczas parsowania YAML-a. Najważniejszym kontekstem jest kontekst inputs, który jest intensywnie wykorzystywany podczas budowania komponentów CI/CD. Weźmy na przykład scenariusz dynamicznego komponentu deploymentu. Chcesz, aby projekt korzystający z tego komponentu przekazał nazwę środowiska jako input. Następnie chcesz użyć tego inputu do ustawienia nazwy stage'a dla joba i określenia konkretnej wersji obrazu Dockera, którą ma spullować. W konfiguracji swojego komponentu wpisujesz pole stage i przypisujesz je do compile-time expression zawierającego inputs kropka environment. Gdy projekt includuje twój komponent, GitLab odczytuje przekazany input environment. Natychmiast ewaluuje to wyrażenie. Wynikowy graf pipeline'u widzi statyczną, zahardcodowaną nazwę stage'a i zahardcodowany tag obrazu. Runner nigdy nie napotyka podwójnych nawiasów. Po prostu otrzymuje standardową konfigurację. Poza inputs, compile-time expressions obsługują również kontekst matrix, który jest obecnie w fazie beta. Kiedy generujesz równoległe joby za pomocą keyworda takiego jak parallel matrix, możesz użyć compile-time expressions, aby dynamicznie dostosowywać właściwości joba w oparciu o konkretne zmienne przypisane do każdej równoległej instancji. Dzięki temu nie musisz duplikować definicji jobów tylko po to, żeby zmienić jedno lub dwa pola dla każdego przebiegu w matrixie. Te wyrażenia są potężniejsze niż podstawowe zastępowanie tekstu. Możesz pisać logikę bezpośrednio w nawiasach, używając operatorów równości, a także logicznych operatorów AND i OR. Możesz sprawdzić, czy input pasuje do konkretnego stringa, i warunkowo zmienić wartość na podstawie wyniku. Masz również dostęp do wbudowanych funkcji. Na przykład funkcja expand vars pozwala ci bezpiecznie wstrzykiwać wartości compile-time do stringa, zachowując jednocześnie standardową składnię zmiennych runtime'owych. Gwarantuje to, że runner nadal otrzymuje zmienne runtime'owe, których oczekuje, bez powodowania konfliktów podczas wczesnego parsowania. Kluczowy wniosek jest taki, że compile-time expressions dają ci natywny mechanizm do tworzenia szablonów grafu pipeline'u, czysto oddzielając logikę generowania struktury od faktycznej egzekucji skryptu. Poświęć trochę czasu na przeczytanie oficjalnej dokumentacji GitLaba, przejrzyj obsługiwane funkcje i spróbuj zdeployować komponent w praktyce. Jeśli masz tematy, które chciałbyś, żebyśmy poruszyli w przyszłej serii, odwiedź stronę devstories dot eu i daj nam znać. Dzięki za spędzenie ze mną tych kilku minut. Do następnego razu, trzymaj się.