🎏 Gitlab CI и docker-compose

13.05.2022

Недавно мы уже рассматривали CI конвейер Gitlab, с тех пор проект, для которого затевался весь DevOps, стал расти и потребовался другой подход в организации непрерывной интеграции.

Теперь нужно запускать ряд последовательных операций анализа и тестов:

  • анализ code-style - новый код должен соответствовать стандартам оформления кода
  • статический анализ - логика кода не должна содержать латентных багов в перспективе (на определенном уровне)
  • unit тесты - каждый юнит продукта должен быть работоспособен
  • server тесты - сервер, с которым связывается продукт, должен работать как ожидается, а если это не так, то это плохой сигнал - мы не можем выкатить в релиз новую версию (к слову эти тесты уже не раз показали свою важность, серверный отдел упорно не хотел писать тесты)
  • system тесты - компоненты системы в имитационной среде должны работать с сервером, как ожидается
После всего перечисленного мы можем с бОльшей долей уверенности выпускать релиз + при помощи автоматизации этих процессов нивелировать человеческие ошибки.

Организация

Можно было бы запихнуть это все в один job, но как-то плохо все в одной куче потому что не видно на каком этапе произошел провал, поэтому раскидаем каждый этап на свой job.

Задания этапов конвейера
Задания этапов конвейера

Ситуацию осложняет факт наличия нескольких сервисов (кроме php нужен mysql) для прохождения последнего этапа, поэтому используется docker-compose (иначе можно было бы сделать по другому).

А еще есть composer, он нужен на каждом этапе, как и зависимости проекта. Но в конце каждого job'a в терминале можно увидеть:

•••
plaintext
Cleaning up project directory and file based variables Job succeeded

Это значит что каждый job очищает после себя артефакты, среди которых зависимости проекта, а без зависимостей не можем продолжать работу. Но если закэшировать нужные пути тогда очистки не будет.

В проекте уже ипользуется файл docker-compose-dev.yml для организации изолированной среды разработки, можно его использовать, так как среда может измениться с новой версией и желательно прямо в репозитории иметь актуальный конфиг.

Executor gitlab-runner'a должен быть shell, через терминал будем поднимать композицию контейнеров.

.gitlab-ci.yml

Схема работы:

  • поднятие композиции контейнеров на дефолтном .pre этапе
  • каждый job выполняет свою работу в этой композиции контейнеров
  • обязательное завершение работы контейнеров на дефолтном .post этапе
Теперь перенесем эту схему на конфиг:
•••
yml
# кэширование артефактов между job'ами cache: paths: - vendor/ stages: - analysis - test # поднятие композиции контейнеров pre-job: stage: .pre script: - docker-compose -f docker-compose-test.yml up -d --force-recreate --build - docker-compose -f docker-compose-test.yml exec -T php composer install # анализ code-style analysis-cs-job: stage: analysis script: - docker-compose -f docker-compose-test.yml exec -T php composer run-script cs # стстический анализ analysis-lint-job: stage: analysis script: - docker-compose -f docker-compose-test.yml exec -T php composer run-script lint # unit тесты test-unit-job: stage: test script: - docker-compose -f docker-compose-test.yml exec -T php vendor/bin/phpunit --colors=always --coverage-text --bootstrap tests/Unit/bootstrap.php tests/Unit/ coverage: '/\s+Lines:\s{2,}(\d+[,.]\d+%)/' # server тесты test-server-job: stage: test script: - docker-compose -f docker-compose-test.yml exec -T php composer run-script test-server # системные тесты test-system-job: stage: test script: - docker-compose -f docker-compose-test.yml exec -T php composer run-script test-system # обязательное завершение работы композиции контейнеров post-job: stage: .post when: always script: - docker-compose -f docker-compose-test.yml down

Результаты

Конфиг docker-compose-dev.yml используемый для разработки на машинах разработчиков пошел в автоматизированную тестовую среду на CI конвейер, что привело к единообразию среды разработки и тестов/анализов.

Из подручных средств был организован один из шагов непрерывной интеграции. Ну не нсовсем из подручных, тесты писались самостоятельно специально для этого.