ДжазТим — надежный технологический партнер

Agile разработка ПО на Java

Внедрение CI/CD на проекте с историей своими силами. Часть 2: Реализация

Введение

В этой статье будет рассказано о фактической реализации процесса внедрения CI/CD на проекте с многолетней историей. Прочитать про начальный этап процесса внедрения можно по ссылке.

После того как была подготовлена проектная документация по CI/CD процессам — нам осталось внедрить запланированные изменения. Как вы помните из первой части, в рамках данного проекта мы планировали внедрить CI/CD силами команды разработки без привлечения DevOps инженера. Основная сложность внедрения состояла в том, что на проекте есть установившиеся процессы, которые плохо поддаются автоматизации.

В предыдущей статье были описаны этапы инициации и планирования проекта, а в данной статье будут описаны этапы выполнения и завершения проекта.

Отдельно надо отметить, что сам процесс внедрения изменений был пошаговым — мы глубоко декомпозировали задачи внедрения и, шаг за шагом, инкрементально, внедрили CI/CD.

Важно отметить, что внедрение нового функционала, особенно если инициатива исходит не от инженеров, часто сопровождается недостатком мотивации и выученной беспомощностью. Поэтому важным пунктом была организация работы с командой. Каждому инженеру досталась своя выделенная задачи и определены ожидания по ним.

В процессе часто происходила потеря фокуса и отклонение от намеченного плана, поэтому в данном контексте очень важным является лидерство на проекте, которое с одной стороны поддерживает мотивацию, а с другой стороны не позволяет сильно отклоняться от намеченных целей.

Процесс внедрения CI/CD был разделен на следующие этапы:

  1. Внедрение системы автоматической сборки приложения.
  2. Установка и настройка Jenkins.
  3. Автоматизированное обновление Frontend сервера в рамках CI/CD.
  4. Автоматизированное обновление Backend сервера в рамках CI/CD.
  5. Обновление кастомизаций для конкретных клиентов.
  6. Обновление баз данных.
  7. Внедрение GUI-тестирования.
  8. Автоматизированный деплой на Live сервер.

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

Среди прочего это открыло нам путь к контейнеризации и выходу на более надежные способы эксплуатации.

Основной рабочий процесс CI/CDРис. 1: Основной рабочий процесс CI/CD

Система автоматической сборки приложения

Первичным условием для внедрения автоматизации стало внедрение системы автоматической сборки приложения. Сложность данного этапа состояла в том, что на проекте давно существовала только система ручной сборки приложения. Существовала специальная утилита, которая подготавливала данные для сборки. Разработчик с помощью этой утилиты создавал специальные файлы шаблонов. После чего в IDE создавал рабочий билд приложения, используя данные файлы.

В рамках автоматизации мы внедрили систему автоматической сборки приложения Maven, которая обертывала использование данной утилиты и позволила полностью автоматизировать сборку приложения.

В рамках данного этапа была также добавлена проверка unit-тестами готового приложения.

Установка и настройка Jenkins

Основным компонентом системы CI/CD безусловно является приложение-оркестратор. В рамках нашего проекта мы использовали Jenkins, так как его функционал полностью отвечал нашим потребностям. Jenkins был установлен на основном тестовом сервере и, шаг за шагом, мы стали реализовывать в нем CI/CD. Итоговый результат можно увидеть на скриншоте ниже.

Основной компонент CI/CDРис. 2: Основной «пайплайн» CI/CD

Основной компонентРис. 3: Основной «пайплайн»

Обновление Frontend сервера

В рамках данного шага мы автоматизировали развертывание frontend приложения на сервере IIS. Так как в данном проекте обновление frontend приложения происходит достаточно редко, то в рамках CI/CD системы мы не рассматривали автоматическую сборку данного приложения. На остановленный сервер деплоился фронтенд приложения, после чего запускался сервер.

Обновление Backend сервера

На этом шаге мы автоматизировали развертывание backend приложения на сервере Tomcat. В Jenkins добавили следующую функциональность:

  1. Сборка нового веб-приложения.
  2. Прохождение unit-тестирования.
  3. Остановка Tomcat.
  4. Копирование файла веб-приложения в Tomcat.
  5. Запуск Tomcat.

В Jenkins мы применили скрипты на Groovy. Это позволило очень сильно переиспользовать код и настройки, что позволило в дальнейшем сильно упростить работы по поддержке всей системы.

Данные практики мы в обязательном порядке применяем на всех наших проектах и с гордостью можем сказать, что нами накоплен большой опыт по правильной настройке и использованию Jenkins.

Обновление кастомизаций для определенных клиентов

Кастомизации для определенных клиентов — это отдельный компонент системы, который позволяет изменять функциональность приложения для отдельных пользователей. Сложность автоматизации данной системы состоит в том, что кастомизация может выполняться в очень широких пределах и по сути является способом интеграции приложения в бизнес системы заказчика.

Соответственно, данная система обладает очень высокой гибкостью, из-за чего сделать автоматизацию оказалось нетривиальной задачей. Возможные изменения затрагивали очень много самых различных систем, требовали контроля за файлами конкретных пользователей и глубокой проработки процесса обновления.

В нашем случае за этот участок работы отвечал отдельный инженер, который только для этой системы сделал полный цикл исследовательских работ — от написания требований и sequence диаграммы до внедрения готового решения. В рамках этой активности нами изначально был сделан сделан proof of concept, потом доработана архитектура приложения и после этого внедрена автоматизация деплоя.

Обновление кастомизаций для определенных клиентовРис. 4: Обновление кастомизаций для определенных клиентов

Обновление баз данных

В качестве СУБД на проекте используется SQL база данных. При этом для каждого конечного клиента создается свой экземпляр БД, который построен одной и той же схеме. Обновление баз данных проходит с помощью технологии Liquibase.

Jenkins в общем pipeline проверяет, требуется ли обновлять базы данных, после чего обновляет каждый инстанс.

Это приводило к очень нестандартным решениям, потому что базы данных надо было обновлять как минимум 3-мя разными способами:

  1. Обновлять все экземпляры БД.
  2. Обновлять выбранные экземпляры БД.
  3. Обновлять все, кроме выбранных БД.

Это приводило к тому, что процесс только апробации и тестирования всего необходимого функционала растянулся более чем на полгода. В процессе были применены несколько различных способов запуска, через Jenkins, через bash скрипт, а в конце концов остановились на том, что jenkins работает напрямую с SDK Liquibase.

Внедрение автоматизированного тестирования

Отдельным, но очень важным элементом CI/CD системы является проведение автоматизированного тестирования. У нас оно реализовано следующим образом. При каждом билде приложения прогоняются все unit тесты.

При этом каждую ночь на тестовом стенде прогоняются GUI-автотесты из master ветки, которые полностью проверяют текущий инстанс на возможную регрессию.

После полного прогона тестов формируется отчет, который с утра анализирует QA Automation инженер.

Конвейер тестирования пользовательского интерфейса 1Рис. 5: Конвейер тестирования пользовательского интерфейса 1

Отчет о тестировании пользовательского интерфейса 2Рис. 6: Отчет о тестировании пользовательского интерфейса 2

Автоматизация на Live сервере

После того, как были выполнены все работы по автоматизации развертывания и тестирования — мы приступили к опытной эксплуатации на тестовом сервере. Тестовый период длился два месяца, за время которого нами была проверена работа всех элементов системы.

По окончании тестового периода — эту же автоматизацию мы стали использовать уже на Live сервере. Это позволило нам автоматизировать работу разработчиков, снизив таким образом вероятность человеческой ошибке при деплое на Live сервер.

Заключение

Как можно заметить, процесс внедрения CI/CD был относительно несложным в первую очередь благодаря нашей тщательной подготовке. Планирование работ и написание качественной документации позволило нам решить задачи внедрения CI/CD непосредственно силами самой команды.

Как итоговый результат — частота поставки выросла в 4-5 раз, надежность работы приложения стала существенно выше, а количество обращений от пользователей меньше.

Процесс разработки и развертывания стал гораздо более прозрачным, теперь стейкхолдеры могут наблюдать сами процесс поставки и даже сами разворачивать себе на стенд требуемый тестовый вариант приложения.