Continuous Integration

11 Maja 2016

Piszemy kod, commitujemy, pushujemy. I jesteśmy potem zajęci, zapominamy o kodzie. W tym czasie ktoś stwierdza, że ściągnie sobie nasze repo. Więc klonuje, pobiera paczki, odpala build i … nie działa.

Powyższe spowodowane jest tym, że programista nie zawsze pamięta by skompilować, uruchomić, przetestować kod po wprowadzeniu zmian. Powinien pamiętać, ale zdarza się, trudno. To jest jeden ze scenariuszy gdzie CI, czyli Continuous Integration, może pomóc.

CI określa szereg czynności, które będą wykonywane po każdym wydarzeniu (np. push). Skrypty CI buduje się tak, aby z czysto sklonowanego repo można było uzyskać żądany efekt. W moim przypadku zaczynam od nuget.exe restore, aby pobrać niezbędne paczki NuGet. Potem następuje budowanie całej solucji, a na koniec testowanie.

Aby uzyskać maksymalną pewność poprawności budowania mojego projektu, zarówno na Windowsie jak i na Linuxie, postanowiłem podpiąć się do dwóch najpopularniejszych systemów CI:

AppVeyor

W oparciu o Windows jedyne co musiałem dodać do mojego projektu to krok 1. czyli NuGet Restore. W zakładce Settings > Build > Before build script wpisałem nuget restore. Następnie uruchamiany jest msbuild, który buduje cały mój projekt. Potem wykrywane i uruchamiane są testy.

Miłym dodatkiem (na razie przeze mnie nie wykorzystywanym) jest feed NuGetowy. Czyli jeśli odpowiednio skonfiguruję projekt, to użytkownik moich bibliotek, zamiast budować je samodzielnie, może pobierać najnowszą wersję przez NuGet prosto z moich buildów.

Travis CI

Travis jest oparty o Linux, więc wymaga pewnych zmian w mojej solucji. Posiadając projekt oparty o WPF nie mógłbym zbudować mojego repozytorium w całości. Aby ustalić które projekty mają być budowane, należy dodać nową konfigurację w ustawieniach solucji.

Configuration Manager Solution Properties

(Rozwiązanie znalazłem na Stack Overflow)

Kiedy rozwiązałem ten problem, wszedłem na stronę Travisa aby zobaczyć jak dodać plik konfiguracyjny .travis.yml. Jest specjalna sekcja poświęcona C#. Doszedłem do takiego ustawienia:

language: csharp
solution: SharpOffice.sln
mono:
  - latest
  - 4.0.0
  - 3.12.0
install:
  - nuget restore SharpOffice.sln
  - nuget install NUnit.Runners -Version 3.2.0 -OutputDirectory testrunner
script:
  - xbuild /p:Configuration=Linux SharpOffice.sln
  - mono ./testrunner/NUnit.ConsoleRunner.3.2.0/tools/nunit3-console.exe ./SharpOffice.Common.Tests/bin/Linux/SharpOffice.Common.Tests.dll

Co spowoduje uruchomienie 3 buildów, po jednym na każdą wersję Mono. Travis pobiera odpowiedni runtime w trakcie buildu, następnie wykonuje kroki ustalone w pliku konfiguracyjnym. A na koniec otrzymujemy Build Status

Artefakty

Dodatkowo można ustalić aby każdy build zostawiał artefakty czyli zbudowane biblioteki. Mój projekt jest jeszcze w zbyt wczesnej fazie aby coś takiego było potrzebne, ale kiedyś może będę to wykorzystywał, jako np. źródło do pobierania aktualizacji.