W codziennej pracy mam nadzieje że każdy z Was korzysta z systemu kontroli wersji, który umożliwia śledzenie wszystkich zmian dokonywanych na plikach. Systemy kontroli wersji dzielą się na trzy grupy:

  • lokalne
  • scentralizowane
  • rozproszone

W dzisiejszym przykładzie wykorzystam rozproszony system kontroli wersji Git. Umiejętność korzystania z Gita w codziennej pracy to podstawowa cecha dobrego programisty. Do przechowywania kodu źródłowego w chmurze można wykorzystać jeden z popularnych usług GitHub, Bitbucket lub GitLab.

Bitbucket

W powyższym artykule postaram się zaprezentować jak dla projektów w .NET Core 2.0 można zastosować ciągłą integracje z wykorzystaniem narzędzia Bitbucket Pipelines. Do pracy wykorzystam maszynę z systemem Ubuntu 16.04. Solucja składa się z dwóch projektów ASP.NET Core Web API (folder src) oraz projektu z testami integracyjnymi w XUnit (folder tests). Do zarządzania projektami wykorzystam .NET Core CLI.

Zanim przejdziemy do etapu implementacji należy założyć konto na Bitbucket i utworzyć publiczne lub prywatne repozytorium.

Generowanie kluczy SSH

W przypadku prywatnego repozytorium w celu pominięcia ciągłego wpisywania hasła dostępu do repozytorium Bitbucket wygeneruję klucze SSH. Przy generowaniu wykorzystam domyślną konfiguracje. W terminalu wpisujemy komendę ssh-keygen i postępujemy zgodnie z wyświetlonymi instrukcjami.

Dodanie publicznego klucza do ustawień Bitbucket

W ramach komendy ssh-keygen została utworzona para kluczy publiczny i prywatny RSA. Klucz publiczny należy skopiować i dodać do ustawień konta na Bitbucket (Bitbucket settings -> SSH keys -> Add key). W celu skopiowania klucza do schowka można użyć w terminalu komendy cat ~/.ssh/id_rsa.pub | xclip -sel clip.

.NET Core CLI

Po wykonaniu powyższych kroków można przejść do pobrania repozytorium i utworzenia projektów z wykorzystaniem wiersza poleceń .NET Core CLI. Dzięki .NET Core CLI zyskaliśmy możliwość w prosty sposób integracji projektu z build serwerem i automatyzacji procesu budowania, testowania i wdrażania aplikacji/usługi. W ramach implementacji wykorzystane zostały następujące komendy:

  • dotnet new (utworzenie nowego projektu, solucji na określonym szablonie)
  • dotnet sln (modyfikacja pliku solucji np. poprzez dodanie, usunięcie projektu)
  • dotnet add refrence (dodanie referencji projektu do projektu)
  • dotnet restore (pobranie zależności do projektu)
  • dotnet build (budowa projektu i wszystkich jego zależności)
  • dotnet test (uruchomienie testów jednostkowych)

Na temat pozostałych komend z .NET Core CLI można przeczytać na stronie Microsoftu 

git clone git@bitbucket.org:devkrpl/pipelines-dotnet.git
cd pipelines-dotnet
mkdir src tests
cd src
dotnet new webapi -n Sample.Api
cd ..
cd tests
dotnet new xunit -n Sample.Tests.EndToEnd
cd ..
dotnet new sln -n Sample
dotnet sln Sample.sln add src/Sample.Api/Sample.Api.csproj tests/Sample.Tests.EndToEnd/Sample.Tests.EndToEnd.csproj 
dotnet add tests/Sample.Tests.EndToEnd/Sample.Tests.EndToEnd.csproj reference src/Sample.Api/Sample.Api.csproj 
git add *
git commit -m "Added projects"
git push origin master

Bitbucket Pipelines

System ciągłej integracji oferuje łatwą konfiguracje przy użyciu plików YAML, które opisują kroki kompilacji. Plik bitbucket-pipelines.yml tworzymy, w katalogu głównym repozytorium w którym znajduje się solucja. Wcięcia w pliku YAML muszą zostać zrobione spacją, nigdy przy użyciu tabulatora. Plik bitbucket-pipelines.yml może definiować wiele konfiguracji kompilacji, z których każda jest potokiem. Bitbucket Pipelines do uruchomienia konfiguracji  wykorzystuje obraz Dockera. Zilustrowana poniżej konfiguracja wykorzystuje obraz microsoft/dotnet:latest. W pliku można zdefiniować jeden z pięciu typów potoku:

  • default
  • branches
  • tags (tylko dla Git)
  • bookmarks (tylko dla Mercurial)
  • custom

W poniższej konfiguracji pipeline będzie uruchamiany dla każdego wypchniętego commita na gałąź master w repozytorium. Gdy dokonamy commita na innej gałęzi pipeline nie zostanie uruchomiony. W przypadku gdybyśmy zdefiniowali pipeline typu default dla commita na innej gałęzi niż master on zostałby wykonany. Pipeline typu default uruchamiany jest dla wszystkich gałęzi, które nie pasują do żadnej innej konfiguracji pipeline. W pipeline mamy zdefiniowane kroki zawierające listę poleceń wykonywanych w procesie kompilacji. W naszym przypadku zostanie zbudowany projekt Sample.Api, oraz zostaną uruchomione testy jednostkowe dla projektu Sample.Tests.EndToEnd. Na potrzeby prezentacji funkcjonalności Bitbucket Pipelines projekty zawierają tylko domyślnie wygenerowany kod.

image: microsoft/dotnet:latest

pipelines:
  branches: 
    master:
      - step: 
          script:
            - cd src/Sample.Api 
            - dotnet restore 
            - dotnet build
            - cd -
            - cd tests/Sample.Tests.EndToEnd
            - dotnet restore
            - dotnet test

Po wypchnięciu commita  z plikiem bitbucket-pipelines.yml na repozytorium należy przejść w repozytorium projektu do zakładki Pipelines i aktywować CI/CD Pipelines. Na stronie Bitbucket istnieje także możliwość stworzenia pliku bitbucket-pipelines.yml z dostępnych szablonów, które można dostosować do swojego projektu.

Dla każdego commita na gałęzi master w zakładce Pipelines zobaczymy status budowania aplikacji/usługi. Dla powyższego commita proces zakończył się powodzeniem. W wersji darmowej narzędzia Bitbucket Pipelines otrzymujemy 50 minut miesięcznie do budowania aplikacji.

I to by było dzisiaj na tyle, a w kolejnym tygodniu na tym blogu poruszę temat Gitlab CI, zapraszam do odwiedzin 🙂