O Continuous Integration

in #polish6 years ago

Wstęp

Chciałem napisać artykuł o konkretnej implementacji CI. Zacząłem pisać wstęp i tak wyszedł właściwie osobny post.
Chyba każdy, kto już chwilę programuje konfigurował środowisko tak, aby automatyzować pewne procesy. Na początku kariery, nie jest to jednak proste. Pamiętam, że była to dla mnie czarna magia. Sam efekt nie był skomplikowany, bo widziałem, że testy przeszły, lub nie. Ale jak to się działo w środku? Co odpalało te testy, gdzie się to odpalało? Skąd github o tym wiedział. Tego nie rozumiałem.

Co to jest Continuous Integration?

Aby nie wchodzić w definicje, w skrócie można powiedzieć, że jest to automatyzowanie pewnych powtarzalnych czynności, które występują w projekcie. Sprowadza się to do tego, że kiedy dostarczamy jakąś funkcjonalność, automatycznie wykonywane jest sprawdzenie kodu (składnia, testy, błędy itp). Często automatyzuje się również deploy na serwery testowe, oraz wspomaga deploy na produkcje. (Przez wspomaganie rozumiem, sprowadzenie deploy-u produkcyjnego do kliknięcia w jeden przycisk)

Jak to działa?

Aby mówić o CI, musimy mieć jakiś serwer, na którym będzie stało odpowiednie oprogramowanie (np Jenkins). Często nazywa się to po prostu “serwerem CI”. Powinna to być oddzielna maszyna, ponieważ proces buildu pochłania zwykle sporo zasobów.
W oprogramowaniu tym, wykonywane są po kolei komendy związane z instalacją i uruchomieniem testów na aplikacji. Generalnie są to te same komendy, które pozwalają nam odpalić testy aplikacji w środowisku lokalnym. Serwer CI współpracuje z odpowiednim pluginem w repozytorium. Zarówno github, bitbucket, czy gitlab, mają takie pluginy.
W github-ie wygląda to tak:

Peek 2018-01-04 00-56.gif

Plugin w repozytorium służy do wyświetlania tego co zrobił CI, oraz do komunikowania się z nim. Trzeba więc zainstalować i skonfigurować plugin w repozytorium, oraz aplikacje CI na serwerze.
Najczęściej konfiguracja sprowadza się to do określenia, kiedy ma się wykonać jakiś proces/build w CI. Oczywiście dla jednego projektu może być kilka różnych procesów / buildów. Ja zwykle robię dwa:

  • odpalenie buildów przy każdym stworzonym pull-requeście
  • odpalenie deploy-u na serwer testowy przy każdym zmergowaniu feature-a do gałęzi dev

Selection_017.png

Przykładowy widok buildów dla poszczególnych gałęzi w bitbucket.com

Jak dokładnie wyglądają polecenia buildu?


zainstaluj aplikacje czyli zbiór poleceń w typu apt-get install nodejs
bundle exec rspec - odpalenie testów
bundle exec rubocop sprawdzenie składni i formatowania kodu
bundle exec reek sprawdzenie jakości kodu

Powyższe komendy są używane do aplikacji napisanej w Ruby.
W zależności od tego, w jakim języku i frameworku napisany jest nasz projekt, polecenia oczywiście będą inne. Ilość poleceń zależy od tego jak dużo narzędzi wykorzystujemy.

Dostępne CI

Na rynku dostępnych jest bardzo dużo różnych CI. Zwykle mają plik konfiguracyjny wg. którego wykonywane są polecenia. Opiszę tylko te narzędzia, które samodzielnie konfigurowałem.


Jenkins
Działa w taki sposób, że instalujemy na własnym serwerze aplikacje Jenkins. Następnie w interface graficznym konfigurujemy projekt. Określamy kiedy build ma się wykonać, podajemy adres repozytorium, klucze autentykacyjne itp. Na koniec w okienku wpisujemy komendy bash-owe które wykonają build. Jenkins ma stosunkowo wysoki próg wejścia. Jak dla mnie jest trochę reliktem przeszłości. Dziś są dostępne dużo łatwiejsze rozwiązania.

Travis
Aby korzystać z Travisa trzeba dodać w repozytorium (testowalem tylko z github) w katalogu głównym plik .travis.yml. W tym pliku wykonujemy komendy jakie mają się wykonać.
Używam travisa kiedy tworzę biblioteki do ruby, ponieważ podczas tworzenia takiej biblioteki automatycznie generuje się plik konfiguracyjny do niego. Dla Open-sourcowych projektów jego używanie jest darmowe. Dodatkowo w pliku readme możemy dodać sexi button(build passing).
Selection_018.png

Przykładowy plik konfiguracyjny dla Travis:

Selection_019.png

GitLab CI
Aby korzystać z CI gitlaba, trzeba mieć własnego hostowanego gitlab-a na jednym serwerze, oraz zainstalować na drugim aplikacje do CI. Instalacja jest łatwa, ale trzeba mieć dwa osobne serwery. Później podobnie jak w przypadku Travis-a mamy plik konfiguracyjny, który dodajemy do głównego katalogu aplikacji. Jego nazwa to .gitlab-ci.yml.
Reszta dzieje się już automagicznie, w zależności od tego co mamy w pliku konfiguracyjnym.
Trzeba wspomnieć, że ma on naprawdę duże możliwości. Poniżej wklejam screen z dokumentacji gitlab . Znajduje się on na stronie: GitLab Documentation. GitLab CI jest oparty na Dockerze.

Selection_020.png

Bitbucket Pipelines
I wreszcie CI któremu chciałem poświęcić ten post, jednak ze względu na przydługawy wstęp napiszę o nim w następnej części. Teraz wspomnę tylko, że dla małych projektów jest darmowy i nic nie trzeba instalować.

Zdjęcie tytułowe pochodzi z https://www.pexels.com

Sort:  

Wydaje się, że dzisiaj nie da się bez CI prowadzić projektu bardzo fajny artykuł. Od siebie dodam, że na Travis CI wersji open-source (darmowej) możemy generować doker-a, gdzie możemy sprawdzić czy projekt działa, lub dużo łatwiej i bezpieczniej go wdrażać u klienta.

pomocna tresc

Cześć @piotr-galas, przydatny post, dzięki! Sam korzystam (w mniejszym lub większym stopniu) z Jenkins i zaciekawiło mnie stwierdzenie, że Jenkins jest reliktem przeszłości. Rozwiniesz? :)

Pozdrawiam

Dobre pytanie, zmusiło mnie do tego aby zrobić mały research. Projekt powstał w 2011, więc nie jest jeszcze taki stary, choć jego początek sięga projektu Hudson i roku 2005. Patrząc w internecie jest jednym z najpopularniejszych CI. Ma też pluginy które właściwie rozszerzają jego funkcjonalność w dowolny sposób.


Moja opinia wynika z tego, że dziś takie rzeczy można zrobić naprawdę dużo prościej. Nie trzeba mieć własnego serwera, konfugurować go, dbać o jego bezpieczeństwo. Moje doświadczenia z Jenkinsem nie są zbyt dobre. Generalnie przynajmniej kilka razy w tygodniu coś się psuło, przez co zamiast pracować rozwiązywałem problemy z bulidami kolegów. Był moment, że jak słyszałem "Piotrek... build mi niprzeszedł. Chyba Jenkins nie działa" robiłem się czerwony.


Myślę, że zdecydowanie łatwiej jest wrzucić do repozytorium plik konfuguracyjny (łatwy i intuicyjny), oparty o DSL zbliżony do Dockera. Reszta dzieje się sama. Zarówno na Bitbucket Pipelines jak i na GitLab CI na których ostatnio pracuje, błędy związane z konfiguracją zdarzają się bardzo rzadko. Wydaje mi się, że w dzisiejszych czasach lepiej jest zapłacić za CI i nie poświęcać czasu na konfigurowanie go.
Jeśli jednak ktoś potrzebuje jakiejś bardzo specyficznej rzeczy, to pewnie Jenkins się przyda.
Innym aspektem jest to, że w swojej karierze widziałem tylko jeden projekt oparty o Jenkinsa, który zresztą sam konfigurowałem i zaczynałem. Taka była decyzja naszego teemu. Wszyskie inne projekty korzystały z rozwiazań typu SAAS.


Chciałem też podkreślić, że jest to moja prywatna opinia i nie chciałem nią nikogo urazić. Post kierowany był raczej do osób które zaczynają przygodę z programowaniem. Weźmy np programistę JS który ma 1 rok doświadczenia. Czy będzie on w stanie postawić CI Jenkinsa? Pewnie miałby z tym problem. A czy byłby w stanie postawić CI oprate np o Bitbucket Pipelines, albo Travisa? Myślę że bez problemu

Cześć @piotr-galas, interesujący i wyczerpujący komentarz :) Dzięki!

Muszę się zgodzić w 100% w kwestii instalacji i konfiguracji Jenkins'a, może to być mozolny proces. Zaczynając z Jenkinsem niejednokrotnie potrzebowałem pomocy administratora, mnóstwo czasu poświęciłem na poszukiwania, instalację i konfigurację wtyczek, a i tak koniec końców pojawiały się problemy. Raz zdarzyło się nawet, że ktoś dostał się do naszego serwera produkcyjnego właśnie poprzez Jenkins'a (build'y były deploy'owane przez SSH-plugin, a Jenkins dostępny z zewnątrz) i odpalił tam sobie algorytm do kopania krytowalut :)

Wydaje mi się, że w dzisiejszych czasach lepiej jest zapłacić za CI i nie poświęcać czasu na konfigurowanie go.

Zgadzam się, natomiast dodałbym od siebie, że niekoniecznie musi to być najlepsza decyzja, gdy potrzebujemy rozwiązania 'szytego na miarę', choćby ze względu na niezliczoną ilość wtyczek do Jenkins, o których wspomniałeś. W przypadku małego zespołu, trafiłeś w sedno.

Powiem szczerze, że po przeczytaniu Twojego komentarza, zaczynam się poważnie zastanawiać nad przetestowaniem Pipelines. Chodziło mi to po głowie od jakiegoś czasu, choćby ze względu na to, że w zespole korzystamy z BitBucket'a - brakowało mi jednak wystarczającego bodźca :)

P.S.: Skoro jesteśmy już przy temacie CI, to czy może ktoś słyszał/korzystał z TeamCity (od JetBrains)?

Korzystałem z TeamCity, na jednym projekcie, ale byłem juniorem i nie zastanawiałem się nad koniguracją. Projekt bazował na testach integrayjnych które trwały straszną ilość czasu. Nie pamiętam dokładnie ile, ale na pewno ponad 1h. TeamCity jakoś sobie z tym radziło. Było kilka równoległych workerów( chyba 4).
Kiedy odchodziłem z projektu, były pomysły aby zmienć TeamCity, bo koszty były zbyt wysokie.

Odnośnie CI i wyboru najodpowiedniejszego polecam fajny artykuł
https://codete.com/blog/make-apps-not-infrastructure/

Z TeamCity co prawda nie korzystałem, ale używam Bamboo i jestem bardzo zadowolony (z bitbucketem)

He he :) też na to zwróciłem uwagę, sam używam tego kombajnu i ciekawy jestem co Piotr miał na myśli :)

Coin Marketplace

STEEM 0.27
TRX 0.13
JST 0.032
BTC 60986.03
ETH 2921.26
USDT 1.00
SBD 3.57