Как мы делали CI и что из этого вышло

27.04.2017
Постановка задачи за 15 секунд - Mail2Task Следующая статья Постановка задачи за 15 секунд - Mail2Task Подводные камни в приложениях Bitrix24 и как их обходить Предыдущая статья Подводные камни в приложениях Bitrix24 и как их обходить

Непрерывная интеграция (CI, англ. Continuous Integration) — практика разработки программного обеспечения, которая заключается в выполнении частых автоматизированных сборок проекта для скорейшего выявления и решения интеграционных проблем.

Все начиналось в далеком 2011-м. Для своих проектов мы начали использовать VCS (контроль версий). Реальной необходимости на тот момент не было, а подобные системы еще не были популярными.

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

В самом начале мы использовали SVN (не к ночи будет помянут). Чуть позднее внедрили в работу Git.

По мере роста количества проектов и репозиториев (равно как и количества сотрудников) на меня, как тимлида, стало обрушиваться огромное количество просьб от сотрудников (типа, “Спули в песок”). Поскольку временные затраты на подобные операции росли, мы написали первую версию собственного веб-инструмента для работы с удаленным репозиторием.

Deploy login

Основной задачей инструмента было выполнять команду git pull.

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

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

Deploy 1st version

По самым скромным оценкам этот инструмент экономит тимлиду около 15-20 часов в месяц, в связи с чем повышает производительность труда, не отвлекая на рутинные операции.

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

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

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

В интерфейс вынесли все основные операции по работе с репозиторием:

Dev deploy tool

А также создали отдельную вкладку для работы с Git и упаковкой изменений в текущей выбранной ветке.

Dev deploy tool with Git

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

Все эти решения экономили огромное количество времени, но никоим образом не решали вопроса автоматического запуска кода на production-сервер (он же PROD).

Для реализации деплоя в бой и десятка различных утилитарных задач, вроде проверки кода через php_codesniffer и т.п., были необходимы десятки скриптов.

Изначальная мысль разработать свою утилиту для выполнения этих задач была отброшена, и мы взяли на вооружение Jenkins.

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

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

CI_2SRV_ru.png

А вот так будет выглядеть трехсерверная конфигурация.

CI два сервера

И в таком решении есть огромный плюс. Такой подход позволяет нам масштабировать деплой на 4,5 и большее количество серверов без лишних проблем и практически с нулевыми трудозатратами.

Используя нашу систему решения для автоматического деплоя мы и создавая задачу в Jenkins, мы запускаем следующую последовательность:

Задача Jenkins ведет мониторинг определенной ветку в Git репозитории. При появлении изменений она автоматически заливает изменения из этой ветки на указанный сервер.

Кроме того, мы используем Jenkins для следующих задач:

  • Копирование базы данных и медиафайлой с PROD-сервера и их загрузка на DEV-сервер.
  • Загрузка базы данных и медиафайлов с DEV на компьютер разработчика

Сам релиз на PROD выглядит следующим образом:

  • На песке используется ветка DEV
  • Функционал тестируется и полностью подготавливается к релизу
  • Тимлид мержит DEV в MASTER и проводит PUSH в репозиторий
  • Дальше запускается Jenkins, который опрашивает репозиторий раз в 30 минут и при наличии изменений заливает их в бой. Перед запуском код тестируется. После окончания деплоя программно очищается кэш и проводится еще десяток мелких процедур.

Мы используем замечательный Jenkins-плагин “Publish Over (SSH|FTP|etc.)”. Он не решает абсолютно всех задач по релизу на PROD, либо выкатывает вообще весь репозиторий.
(Хотя с помощью этого же плагина можно выполнять команды на удаленном сервере.)

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

  1. Выкатывание релиза происходит в полностью автоматизированном режиме, больше не требует часов скурпулезной работы и занимает считанные минуты.
  2. Решение позволило полностью синхронизировать PROD и DEV. Благодаря этому вероятность появления ошибок и багов на релизном продукте практически равны нулю.
  3. Чем больше сотрудников-программистов одновременно работает над проектом - тем больше выгода от внедрения CI. Благодаря созданию отдельных веток под отдельные задачи не произойдет никаких серьезных ошибок и пересечения разных задач. А вероятность ошибок от человеческого фактора при сборке практически сведена к нулю.
давайте обсудим ваш проект
давайте обсудим ваш проект