Wpis kontynuuje serie o systemach ciągłej integracji. Za każdym razem, gdy wypychamy wprowadzone zmiany w kodzie źródłowym do głównego repozytorium, system CI powinien uruchomić kompilacje, a następnie wykonać testy. Dzięki temu unikamy sytuacji że po dniach, tygodniach wypychania zmian do repozytorium, kod komponentów nie współpracuje z innymi komponentami systemu. Mam nadzieje że traktujesz poważnie czerwone statusy w systemie, a nie spychasz je na bok. Jeśli odpowiedziałeś/odpowiedziałaś tak to ten wpis o dzisiejszym bohaterze GitLab jest dla Ciebie. Odsyłam także do wcześniejszego wpisu o Bitbucket Pipelines.

Kilka słów o GitLab

GitLab to nie tylko serwis do hostowania publicznych i prywatnych repozytoriów kodu, ale także platforma udostępniająca narzędzia do zarządzania zadaniami, wersjonowaniem oprogramowania,  procesem continuous integration i continuous delivery. Platforma GitLab w całości jest udostępniona jako open source. W 2017 roku o GitLab było głośno w mediach w skutek ich wpadki. Problem dotyczył usunięcia bazy danych na serwerze produkcyjnym przez administratora, oraz zawodnego mechanizmu przywracania kopii zapasowej. Każdej firmie taka sytuacja może przydarzyć się. Warto pamiętać że w przypadku awarii firmy hostującej repozytoria  np. GitHub, Bitbucket, GitLab gdy korzystamy z rozproszonego systemu kontroli wersji możemy przenieść repozytoria z historią z lokalnego komputera do innej firmy hostującej. W przypadku scentralizowanego systemu kontroli wersji jesteśmy uzależnieni od mechanizmu backupu.

GitLab CI/CD

GitLab CI/CD to narzędzie do budowania, testowania, wdrażania i monitorowania aplikacji. GitLab CI/CD jest zintegrowane z repozytorium kodu GitLab. GitLab Server jest koordynatorem zadań, który zgodnie  z konfiguracją repozytorium uruchamia procesy na podłączonych do niego maszynach. Gitlab Runner, który przetwarza kompilacje może być zarejestrowany na serwerach GitLab albo maszynach skonfigurowanych przez klienta.

Instalacja GitLab Runner

W celu sprawdzenia, czy dla danego repozytorium skonfigurowany jest Runner w projekcie przechodzimy  do Settings -> CI / CD -> Runners settings. Runner jest procesem, który uruchamia zadania. GitLab umożliwia nam stworzenie własnego Runnera (Specific Runners) lub wykorzystanie Runnera dostarczonego przez GitLab (Shared Runners). Aktywowanie Shared Runner jest bardzo proste, wystarczy kliknąć „Enable shared Runners”. W drugim przypadku GitLab Runner na stacji lokalnej do kompilacji projektu będzie wymagał zainstalowanego Dockera (Instalacja Dockera na Ubuntu). W celu instalacji własnego Runnera na stacji lokalnej (Ubuntu 16.04) dodajemy oficjalne repozytorium GitLab.

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash

Instalujemy najnowszą wersję GitLab Runner.

sudo apt-get install gitlab-runner

Od wersji GitLab Runner 10 została zmieniona nazwa z gitlab-ci-multi-runner na gitlab-runner.

Rejestracja Runner

Rejestracja Runner polega na powiązaniu Runnera z konkretnym projektem GitLab. Każdy projekt na GitLab posiada unikalny token, który używany jest przez Runner do komunikacji z GitLab przez jego API. Token dostępny jest dla danego repozytorium w zakładce Settings -> CI / CD -> Runners settings -> Specific Runners.

W celu uruchomienia rejestracji Runnera pod Ubuntu należy wykonać poniższą komende.

sudo gitlab-runner register

W ramach komendy należy podać między innymi następujące informacje:

  • URL GitLab: https://gitlab.com/
  • Token dla projektu/repozytorium na GitLab
  • Opis dla Runnera
  • Tagi określające dla jakich typów zadań jest Runner
  • Executor: docker
  • Domyślny obraz Dockera: microsoft/dotnet:latest

W przypadku gdy nie zostanie zdefiniowany obraz Dockera w pliku .gitlab-ci.yml zostanie pobrany domyślny obraz Docker, który został podany w trakcie rejestracji Runnera. Po zakończeniu konfiguracji Runner jest gotowy do pracy.

Konfiguracja .gitlab-ci.yml

W celu prezentacji procesu ciągłej integracji wykorzystam solucje z dwoma projektami .NET Core stworzonymi na potrzeby wpisu Bitbucket Pipelines . Przechodzę do folderu w którym znajduje się plik solucji i wykonuję poniższe komendy. W ramach operacji tworzę nowe lokalne repozytorium git, następnie dodaję zdalne repozytorium i wypycham pliki na zewnątrz czyli do GitLab.

git init
git remote add origin git@gitlab.com:devKR/pipelines-dotnet.git
git add .
git commit -m "Initial commit"
git push -u origin master

W celu wykorzystania usługi ciągłej integracji należy plik .gitlab-ci.yml dodać do głównego katalogu repozytorium. Plik .gitlab-ci.yml służy do skonfigurowania ciągłej integracji dla projektu. Zgodnie z notacją wcięcia w pliku YAML muszą zostać zrobione spacją, nigdy przy użyciu tabulatora.

image: microsoft/dotnet:latest

stages:
  - build
  - test

build-master:
  stage: build
  script:
    - 'cd src/Sample.Api' 
    - 'dotnet restore' 
    - 'dotnet build'
  only:
    - master

test-master:
  stage: test
  script:
    - 'cd tests/Sample.Tests.EndToEnd'
    - 'dotnet restore'
    - 'dotnet test'
  only:
  - master

Pipeline wykorzystuje obraz Docker microsoft/dotnet:latest. W ramach pliku zostały zdefiniowane dwa zadania (jobs) o nazwach build-master i test-master. Specyfikacja stages umożliwia tworzenie wieloetapowych potoków. Wyróżniamy trzy typy stages:

  • build
  • test
  • deploy

Wszystkie zadania na danym stage kompilowane są równolegle. Zadania następnego etapu uruchamiane są po zakończonych pozytywnie zadaniach z poprzedniego etapu.W powyższym przypadku jeśli zadania z etapu build zostaną pozytywnie zakończone wtedy następnie zostaną wykonane testy z etapu test. W sekcji script definiowane są komendy które wykonywane są w ramach zadania. W sekcji only definiowana jest nazwa brancha dla którego zostanie wywołane zadanie. Więcej o możliwościach konfiguracji pliku .gitlab-ci.yml  można przeczytać na stronie GitLab. Po wypchnięciu pliku na zdalne repozytorium zostanie uruchomiony pipeline, jeśli wszystko zostało skonfigurowane prawidłowo uzyskamy pozytywny wynik.

W wpisie zaprezentowałem wdrożenie procesu ciągłej integracji dla aplikacji .NET Core z wykorzystaniem narzędzia GitLab CI. Kolejny wpis o ciągłej integracji pojawi się jeszcze w tym miesiącu. Jednak teraz odskoczę od tematu i w następnym wpisie poruszę temat dobrych praktyk w testach jednostkowych. Chcesz być na bieżąco z wpisami na moim blogu to zapraszam na Twittera.