Dawid Panfil

CI/CD – konfigurujemy autodeploy na gitlab.com

Automatyzacja pracy jest dla nas bardzo ważnym czynnikiem. Nie tylko dlatego, że musimy mniej robić. Najważniejsze czynniki to optymalizujemy swoją pracę, możemy wykonać więcej czynności, a zarazem więcej zarobić.

Dużo plusów prawda? Może być ich jeszcze więcej! Jednak o tym będę pisał w kolejnych artykułach, bo mieliśmy już statyczną analizę kodu, teraz mamy automatyczne aktualizowanie naszej aplikacji, a przecież ona też może się sama testować i wysłać nam informacje jak się popsuje. Także minimum dwa tematy jeszcze mamy do omówienia.

Jednak na początku prosty słowniczek.

CI i CD czyli Continuous Integration i Continuous Delivery

Z angielskiego na nasze jest to ciągła integracja i ciągłe dostarczanie. Ja się w tym wpisie nie będę zagłębiał w to, ponieważ jest to wątek na osobny artykuł. Dla nas najważniejszą informacją jest, że jest to proces dostarczania aplikacji polegający na tym, że po każdym commicie/mergu uruchamia się napisany przez nas skrypt, który aktualizuje nasze oprogramowanie.

Pipeline – po krokach do celu

Gdzie naszym celem jest automatyzacja pracy. Cały proces CI/CD dzieli się na kilka elementów:

  • pisanie kodu
  • kompilacja
  • testy
  • deploy na produkcje

Przy każdym commicie musisz przejść cały ten proces i jak w którymś momencie się coś wyspie, to po prostu kończymy integrację. Programista musi poprawić co popsuł i jeszcze raz wypuścić zmiany i znowu na nowo przechodzimy ten proces. Pojedynczy taki proces to właśnie pipeline.

Deployment – czyli wdrażamy

Ostatnie ważne pojęcie czyli deployment. Oznacza to nic innego jak wrzucenie na serwer. Koniec. Jedna ważna zasada: lepiej nie robić tego w piątki o 15 jak kończysz pracę 🙂

Budowa pliku gitlab-ci

Jeśli korzystałeś kiedykolwiek z dockera to jesteś w domu, jak nie.. no cóż będzie Ci troszkę trudniej, ale bez obaw. To nie jest wyjątkowo trudne.

To co musisz wiedzieć, to możliwości takiego pliku są bardzo duże. Możesz m.in:

  • Wykorzystywać obrazy dockera
  • Budować aplikacje
  • Wykonywać polecenia w shell

Czyli w dużym skrócie możesz zautomatyzować swoją pracę. Czy wykonamy rsync, czy scp, czy zwykłe git pull – to bez różnicy. Wszystko jest dozwolone.

Podstawowy plik wygląda tak:


image: php:7.2

stages:
  - build
  - test
  - deploy

compile:
  stage: build
  script:
    - apt-get update -yqq
    - apt-get install git -yqq
    - apt-get install wget -yqq
    - apt-get install zlib1g-dev libzip-dev -yqq
    - apt-get install libxml2-dev wget libpng-dev libjpeg-dev -yqq
    - docker-php-ext-install pdo_mysql mbstring zip gd

    # Install composer
    - curl -sS https://getcomposer.org/installer | php

    # Install all project dependencies
    - php composer.phar config cache-files-dir .composer-cache/
    - php composer.phar install

  artifacts:
    paths:
      - vendor/
    expire_in: 1 days
    when: always
  cache:
    paths:
      - vendor/

test:phpunit:
  stage: test
  allow_failure: false
  before_script:
    - pecl install xdebug
    - docker-php-ext-enable xdebug
  script:
    - vendor/bin/phpunit --coverage-text --colors=never

test:code_style:
  stage: test
  allow_failure: true
  script:
    - vendor/bin/phpcs src --standard=PSR2 --ignore=src/DataFixtures/*,src/Migrations/*

test:code_quality:
  stage: test
  allow_failure: true
  script:
    - vendor/bin/phpstan analyse src -c phpstan.neon

test:mess_detector:
  stage: test
  allow_failure: true
  script:
    -  cat phpmd.xml
    -  vendor/bin/phpmd src text phpmd.xml

deploy:
  stage: deploy
  only:
    - production
  allow_failure: false
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan gotu-jemy.pl > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts

  script:
    - ssh  user@host  "cd /var/www/html &&
                               git pull &&
                               php composer.phar install &&
                               rm -rf var/cache/* &&
                               chmod 777 -R var/cache &&
                               bin/console d:m:m -q -e dev"

Zanim zacznę tłumaczyć linijka po linijce. Zobacz jeszcze ten obrazek:

Przykładowy Pipline

Teraz przyjrzyj się budowie pliku i wyłap w nim build, test, deploy oraz nazwy compile, test:code_quality, test:phpunit i znowu deploy

Więc za poszczególne „duże etapy” odpowiada sekcja stage:


stages:
  - build
  - test
  - deploy

Następnie masz pojedyncze subsekcje takie jak właśnie compile, test:phpunit i tak dalej. Dlatego nie będziemy się nad nimi wszystkimi skupiać.

ETAP 1 – Budowanie



compile:
  stage: build
  script:
    - apt-get update -yqq
    - apt-get install git -yqq
    - apt-get install wget -yqq
    - apt-get install zlib1g-dev libzip-dev -yqq
    - apt-get install libxml2-dev wget libpng-dev libjpeg-dev -yqq
    - docker-php-ext-install pdo_mysql mbstring zip gd

    # Install composer
    - curl -sS https://getcomposer.org/installer | php

    # Install all project dependencies
    - php composer.phar config cache-files-dir .composer-cache/
    - php composer.phar install
  artifacts:
    paths:
      - vendor/
    expire_in: 1 days
    when: always
  cache:
    paths:
      - vendor/

Moim zdaniem najtrudniejszy etap. W gałęzi script musimy zainstalować wszystko po kolei tak jakbyśmy pierwszy raz instalowali aplikację. Muszą być tu wszystkie zależności jakie występują oraz zbudować aplikację. Czyli w tym wypadku uruchomienie composera oraz zapisanie go do tak zwanego artefaktu, który będzie przechowywany przez jeden dzień.

Artefakt, będzie się przewijać przez cały plik, bo np w wypadku aplikacji na angulara, ja tutaj wrzucam wszystko co wyjdzie z polecenia ng build –prod i taką paczkę wgrywam na serwer. Taki artefakt, możesz sobie potem pobrać przez ten jeden dzień i przeglądać co tam wyszło lub przekazać do następnego etapu.

Etap 2 – testy


test:phpunit:
  stage: test
  allow_failure: false
  before_script:
    - pecl install xdebug
    - docker-php-ext-enable xdebug
  script:
    - vendor/bin/phpunit --coverage-text --colors=never

Z testów opiszę Wam tylko ten element, bo reszta się najzwyczajniej w świecie powtarza i w zależności od potrzeb potrzeb możesz sobie tutaj wrzucać wszystko.

W porównaniu do etapu compile mamy tutaj kilka nowości. Pierwsza allow_failture informuje czy pipilne po napotkaniu błędu ma się przerywać czy nie. Po prostu czasem bez sensu przerywać cały proces, gdy w kodzie są dwie spacje za dużo, ale w wypadku testów… coż jak się wysypią to i aplikacja także, dlatego tu nie wolno pozwolić się wysypać.

before_script – jest to takie specjalne miejsce, gdzie możesz doinstalować brakujące rzeczy jak np właśnie xdebug po to, aby wywołać bezpośredni skrypt.

Zauważ, że nie uruchomiliśmy teraz composera.

Etap ostatni – deploy


deploy:
  stage: deploy
  only:
    - production
  allow_failure: false
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan gotu-jemy.pl > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts

  script:
    - ssh  lgin@host  "cd /var/www/html &&
                               git pull &&
                               php composer.phar install &&
                               rm -rf var/cache/* &&
                               chmod 777 -R var/cache &&
                               bin/console d:m:m -q -e dev"

Tutaj też mamy fajny smaczek: only: informujący dla jakich branchy ma się uruchamiać deploy. W ten sposób możesz w prosty sposób skonfigurować serwer testowy i produkcyjny.

Kolejnym smaczkiem jest zmienna: $SSH_PRIVATE_KEY. Zmienne można zapisywać na dwa sposoby. Pierwszy to wchodzisz w gitlabie w Settings -> CI/CD i tam wstawiasz sobie taką zmienną. Natomiast drugi prostszy, tworzysz sobie zmienne w tym pliku, ale jak to zrobić Ci nie powiem 🙂 Jak poszukasz, to łatwiej przyswoisz.

To już jest koniec…

No i to na tyle. Wiem, że mało co tutaj wyjaśniłem, ale to na prawdę jest bardzo proste. Więcej czasu straciłem na połączenie SSH i używanie klucza, niż skonfigurowanie całej reszty etapów. Polecam Ci się pobawić z tymi wszystkimi etapami. Praca z tym jest bardzo przyjemna i na pewno pomoże zaoszczędzić sporo czasu. Przy następnym projekcie nawet policzę dokładnie ile 😉

Jeśli jednak jest dla Ciebie coś niezrozumiałego to śmiało pytaj w komentarzu w miarę możliwości Ciebie pokieruje na właściwe tory, bo w tym wpisie nie chciałem Ci dawać wszystkiego na tacy, ale pokazać, że coś takiego istnieje. Jest to proste w budowie i mega ułatwiające życie. Wystarczy, że na początku skupisz się na celu: automatyzacja pracy, a nie na ideologi CI/CD. Czym jest to całe CI/CD dowiesz się wraz z używaniem tego i dopasowywaniem do swoich wymagań.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *