data.mdx.frontmatter.hero_image

.NET Core – Konfiguracja Gitlab CI

2017-09-13 | .NET, Docker, Gitlab | bd90

Dawno już nie było wpisu o Gitlab-ie. Jeszcze dawniej nie jadłem sałatki, acz nie przesadzajmy ze skrajnościami. Zafascynowany ostatnio możliwościami jakie daje .NET core chciałbym wam krótko przedstawić sposób na wykorzystanie Gitlab CI w aplikacjach opartych tę technologię.

W tym wpisie poruszę wykorzystanie:

  • Gitlab CI Runnera do uruchamiania procesu lokalnie
  • Docker-a i Gitlab CI do budowania obrazu na każdym commit-cie
  • Gitlab CI do uruchamiania testów

Zacznijmy od wygenerowania aplikacji

Nie zaskoczę informując, że należy rozpocząć od wygenerowania aplikacji za pomocą dotnet CLI. Na swoim blogu już kilka razy opisywałem jak to zrobić, więc nie będę tutaj dublował treści i wypisywał wszystkich komend. Zapraszam do lektury wcześniejszych postów.

Pokrótce opiszę strukturę swojego projektu. Będzie składał się z trzech części:

  • scripts -> do przechowywania skryptów *.sh, które będziemy uruchamiać za pomocą naszego pipeline Gitlab-a
  • src -> miejsce do trzymania kodu źródłowego naszej aplikacji
  • tests -> miejsce do trzymania testów

Po założeniu wygodnych kapci, zrobieniu ciepłego kakałka i wykonaniu wstępnych czynności otrzymujemy następującą strukturę projektu:

. |- scripts |- src | |- Application.csproj |- tests | |- Application.Tests.csproj |- Application.sln

Jako aplikacje testową polecam wygenerować pustą aplikację mvc bez autoryzacji, natomiast jako aplikację do testów polecam stworzyć projekt xUnit. Następnie, jeżeli chcecie korzystać z Visual Studio lub Visual Studio for Mac, polecam stworzenie pliku solucji, do którego trzeba dodać dwa pozostałe projekty jako referencję.

Tworzymy konfigurację Gitlab CI

Aby wykorzystać możliwości Gitlab CI musimy najpierw w głównym katalogu projektu stworzyć plik konfiguracji .gitlab-ci.yml. Uzupełniamy go zgodnie z notacją YAML. Dokumentację, jak i opis możliwości, możecie znaleźć tutaj.

Jednym z fajniejszych feater-ów dostępnych w tej konfiguracji jest budowanie pipeline na podstawie ogólnodostępnego obrazu docker-a znajdującego się w serwisie docker hub. Wystarczy pod kluczem "image" podać nazwę obrazu, na podstawie którego chcemy zbudować naszą aplikację.

Inne, bardzo przydatne, narzędzie możemy znaleźć pod kluczem "before_script". Pozwala nam na uruchomienie pewnych działań jeszcze przed wykonaniem procesu budowania aplikacji. Jest to idealne miejsce na pobranie zależności projektu czyli wykonanie komendy "dotnet restore", "npm i" czy każdego innego package manager-a, który tego wymaga.

Przykładowy plik .gitlab-ci.yml może wyglądać następująco:

image : microsoft/dotnet:latest
stages:
  - build
before_script:
  - 'dotnet restore'
build:
 stage: build
 script:
  - 'dotnet build'
 only:
   - master

Pod kluczem "before_script" znajduje się zdefiniowane zadanie o nazwie "build", które należy do fazy "build". Ma na celu uruchomienie komendy "dotnet build" i zadziałać tylko na branchu "master".

Lokalne uruchomienie Gitlab CI Runner

Jeżeli lubicie tak jak ja "poczuć" na własnej lokalnej maszynie, jak to jest używać takich narzędzi automatyzujących pewne procesy, to pewnie spodoba wam się możliwość uruchomienia całego procesu Gitlab CI lokalnie. Jest to banalnie proste... wymaga to raptem 3 kroków, aby sprawdzić czy przypadkiem nasze zmiany w kodzie nie wywalą pipeline-a :). Ok, wiem, że nikt poza mną nie jara się jak ja takimi rzeczami, acz ta wiedza może okazać się przydatna.

Instalacja Gitlab CI Multi Runner

Na początku instalujemy "runnera", który pozwoli nam uruchamiać lokalne pipeline-y.

Jest kilka sposobów by go zainstalować, ja nie lubiąc sobie utrudniać wybrałem najprostszy. Ogarnąłem to za pomocą brew, packet manager-a dla Mac OS-a.

$ brew install gitlab-ci-multi-runner

Inne sposoby instalacji jak i tutoriale instalacji na innych platformach możecie znaleźć w oficjalnej dokumentacji Gitlab-a

Stworzenie repozytorium GIT-a

Drugim krokiem jest stworzenie lokalnego repozytorium GIT i dodaniu do niego naszego projektu. Możemy to zrobić za pomocą komend

$ git init
$ git add .
$ git commit -m "Initial Commit"

Bez tego otrzymamy dość nieprzyjemnie wyglądający błąd

Uruchomienie lokalnego runner-a

W tym momencie zauważyliście, że definicja słowa "krótko" jest zależna od punktu widzenia. Budujcie jednak w sobie siły, gdyż zbliżamy się do końca. Uruchomiamy runner-a Gitlab CI. Wykonujemy to za pomocą komendy:

$ gitlab-runner exec docker build

Argument exec oznacza uruchomienie runner-a o silniku (executor) docker, który ma uruchomić zadanie "build" zdefiniowane w pliku .gitlab-ci.yml.

Mimo tego że mam dość mocnego laptop-a, to uruchomienie całego procesu razem ze ściągnięciem wszystkich jego zależności, podstawowej wersji obrazu docker-a, zbudowanie obrazu, następnie projektu.... to musi trochę zająć. No, chyba, że mamy do dyspozycji światłowód i 16 rdzeniowy procesor...

Jak widać na powyższym obrazku kilka minut cierpliwości pozwoliło uzyskać potwierdzenie, iż wszystko się udało.:)

Dzięki lokalnemu uruchamianiu runner-ów Gitlab CI możemy zdecydowanie zmniejszyć zużycie darmowych minut w pipeline poprzez uniknięcie commit-ów typu "Missing **service in gitlab-ci" (które jeszcze do niedawna często mi się zdarzały).

Uruchomienie Testów w Pipeline

Najprostszą implementacją uruchamiania testów w usłudze CI jest po prostu dopisanie odpowiednich poleceń konsoli w zadaniu "build" znajdującym się w pliku .gitlab-ci.yml. Wygląda to następująco:

build:
 stage: build
 script:
  - 'dotnet build'
  - 'cd tests/Application.Tests'
  - 'dotnet test'

Oczywiście możemy to wynieść do osobnego pliku nazwanego na przykład run-tests.sh i uruchomić go za pomocą konsoli. Wtedy zawartość wyglądała by następująco:

cd tests/Application.Tests
dotnet test

Natomiast zadanie "build" musielibyśmy zmodyfikować do następującej formy:

build:
 stage: build
 script:
  - 'dotnet build'
  - 'chmod -R +x ./scripts'
  - 'scripts/run-tests.sh'

Musimy tutaj pamiętać o nadaniu praw do uruchamiania katalogowi scripts inaczej nasz pipeline może się wywalać na próbie uruchamiania pliku bez odpowiednich praw w systemie.

Teraz pewnie nasuwa się pytanie co takim zabiegiem osiągnęliśmy? Przecież nie dość, że nasze zadanie znajdujące się w pliku .gitlab-ci.yml (nie jest nawet o linijkę krótsze), to posiadamy dodatkowo plik, który musimy utrzymywać.

Wartością dodaną w takim rozwiązaniu jest to, że możemy w prosty sposób tworzyć nowe pliku *.sh w katalogu scripts i je uruchamiać, np. tworzenie plików odpowiedzialnych za uaktualnienie obrazu w serwisie docker hub. Ewentualnie otrzymaliśmy możliwość stworzenia automatycznego deploy-a dokumentacji na wybrany serwer.

Podsumowanie

W dzisiejszym poście pokazałem wam jak za pomocą Gitlab CI na każdym commit-cie, zbudować aplikację, uruchomić testy, a także jak za pomocą paczki gitlab-ci-multi-runner uruchomić to wszystko na waszej lokalnej maszynie.

A w niedługim czasie wracam do opisywania możliwości samego docker-a :)

Do następnego!

Cześć :)

By Bd90 | 13-09-2017 | .NET, Docker, Gitlab