Хочу представить Вам нашу концепцию Continuous Delivery (далее, CD) применительно к основной CMS в которой нашу компания ведет разработку – Sitecore. Наша концепция CD зиждется на трех китах:
- Система контроля версий – Git (в принципе, можно применять и к другим, но Git наиболее удобен в виду того, что ветки в нем весьма просты, быстры и дешевы)
- CI сервер – TeamCity
- Код, который собственно и осуществляет всю доставку, установку и обработку (скрипты и дополнительные исполняемые файлы)
В данной статье, я попробую описать все вовлеченные аспекты.
GIT
Выбор данной системы контроля версий обусловлен нашей концепцией CD, в которой мы имеем три основных ветки в каждом репозитории: dev, acceptance и master. В соотвествии с названиями каждая ветка отражает состояние кода на одном из трех серверов:
- Dev = QA, внутренний сервер, доступный только в нашей сети. На нем производиться основное тестирование
- Acceptance = acceptance сервер, доступный как их нашей сети, так и заказчикам, но не доступен для остальных интернет пользователей
- Master = production сервер, доступный всем.
Вся разработка начинается и ведется в отдельной ветке, корнем которой является master. По завершению разработки происходит мерж в dev, и задача отдается на тестирование.
Если были найдены какие-либо баги – фикс в ветке, мерж и ретестирование.
После того, как тестер сочтет задачу выполненной – происходит мерж в acceptance, доставка и задача отдается на проверку тестерам и заказчику. Если были найдены какие-либо проблемы – снова повторяется вышеописанный процесс.
Если задача завершена по мнению заказчика – происходит мерж ветки, в которой велась разработка в master и доставка на продакшн.
Таким образом, Git является весьма важной составляющей нашего процесса разработки и доставки благодаря простым и быстрым веткам и простоте управления.
TeamCity и процесс доставки с вовлеченными скриптами/приложениями
Простой в настройке, бесплатный для небольших проектов (не более 20 билд конфигураций), отлично понимает большинство распространенных систем контроля версий (в том числе и избранный нами Git), обладает встроенными раннерами для MSBuild, nANT, Visual Studio, а также предоставляет доступ к своему restAPI для получения данных и управления конфигами. На мой взгляд, один из наиболее удобных в своем классе билд серверов (как впрочем, и прочая продукция компании JetBrains). Также, одной весьма удобной фишкой TeamCity является возможность конфигурировать параметры на уровне проекта или на уровне билда прямо через веб-интерфейс. Возможна конфигурация параметров на уровне сервера, а также доступ к системным параметрам хоста (например, PATH).
Типичный билд для проекта, обеспечивающий автоматическую доставку и проверку, что веб-приложение после доставки живо (страница сайта возвращает код 200) состоит из следующих конфигурационных аспектов:
Общие настройки: по результатам каждого билда мы собираем артефакты – архив с веб-приложением, архив с пекеджами (Sitecore использует для доставки между средами специальным способом созданные и заархивированные xml файлы, которые мы и называем пекеджами) и архив с SQL скриптами, в случае если решение использует дополнительные базы данных. А также автоинкрементируемый счетчик билдов, который используется во встроенном в TeamCity AssemblyInfo патчере, инкрементируя версию сборки.
Настройки системы контроля версий: в TeamCity просты до безобразия и легко конфигурируются. Единственный интересный момент тут – это возможность ставить теги по результатам билда, что, теоритически, позволяет вернуться именно к тому коду, в котором была/появилась какая-либо проблема. По возможности, тут используется инкрементальный чекаут с тем, чтобы ускорить билд и снизить траффик.
Собственно, сам билд:
- Билд и паблиш солюшена средствами Visual Studio (VS нужной версии должна быть установлена на сервере). Указываем путь к sln файлу, переменной указываем какую билд-конфигурацию для этого sln файла вызывать (каждый проект имеет несколько билд конфигураций для каждой вовлеченной среды). Паблиш выполняется в локальную папку на сервере, так как прямо на нужный сервер не получилось организовать доставку средствами MS Publish Tool. Первая и последняя проблема, на которой я споткнулся, было то, что мы находимся в разных доменах. Если произошла ошибка MSBuild – билд останавливается, и отправляется информационное сообщение следующим персонам: людям, чьи коммиты участвовали в билде, билд инжинеру и тестерам.
- Подготовка запаблишенных файлов и целевого приложения к установке пекеджей(скрипт). Ввиду того, что по умолчанию в Sitecore запрещено создание нодов в базе данных, содержащих специальные символы языков и зарезервированные символы, а во время разработки без них иногда обойтись не получается – в этом шаге на целевое приложение доставляется специальный патч конфиг, который разрешает использование данных символов. В этом же шаге после доставки патч конфига, который вызывает рестарт приложения, используется wget, чтобы получить главную страницу сайта. Таким образом, обеспечивается работоспособность приложения и готовность к следующему шагу.
- Доставка нодов в базы данных Sitecore. На веб-приложение развернут WCF сервис, который принимает пекеджи и устанавливает их (напомню — сайткор использует для доставки между средами специальным способом созданные и заархивированные xml файлы, которые мы и называем пекеджами), что позволяет автоматизировать эту процедуру следующим образом: при разработке разработчик складывает необходимые для доставки в целевое приложение пекеджи в специально отведенную папку, которая также храниться в сурс-контроле. TeamCity самостоятельно собирает данные об изменениях, участвующих в данном билде и предоставляет к ним доступ через restAPI. Приложение, отвечающее за доставку, считывает xml из restAPI, выбирает участвующие в билде пекеджи и передает их WCF сервису, после чего WCF сервис их устанавливает. Все необходимые данные для приложения-сборщика передаются через параметры, которые сконфигурированы на уровне проекта, так как они одинаковы для всего репозитория. К сожалению, тут есть одна проблема, связанная с WCF сервисом и настройками целевого приложения: если размер пекеджа слишком велик, или же его установка идет более 20 минут – сервис рвет соединение. Если произошла ошибка – сервис возвращает ошибку, билд останавливается, уведомления рассылаются тем же персонам, что и в первом шаге. WCF сервис будет вызываться только в том случае, если есть что доставлять в Sitecore, что также способствует ускорению билда.
- Паблиш нодов в контентную базу данных. Ввиду того, что Sitecore работает с двумя базами данных (master – в которой ведется создание контента и web – из которой контент доставляется конечному пользователю), было создано еще одно приложение для осуществления встроенного в Sitecore процесса переноса данных из master’а в web базу, который называется Паблиш. Работает данное приложение по тому же принципу, что и приложение из шага 3. Разработчик коммитит файл, в котором построчно описаны ноды, которые необходимо запаблишить, приложение через restAPI достает эти файлы (файлы выбираются из коммита из определенной папки в репозитории, ограничение состоит в том, что файлы должны иметь определённое расширение), вычитывает содержимое файлов и передает его WCF сервису, который, в свою очередь, и паблишит ноды с их детьми. В отличии от предыдущего шага, при возникновении ошибки в этом шаге билд не останавливается. WCF сервис будет вызываться только в том случае, если есть что паблишить в Sitecore, что также способствует ускорению.
- Подготовка кода и доставка на целевой сервер. В этом шаге обычный cmd скрипт пакует запаблишенный солюшен и через SSH туннель доставляет получившийся архив на целевой сервер во временную директорию, распаковывавая архив туда же. После чего в папку веб-приложения помещается App_Offline.htm, что остановливает веб-приложение и позволяет выводить пользователям сообщение о том, что в данный момент приложение обновляется.
- (Опциональный шаг) Обновление стороннних баз данных. Если приложение использует не только стандартные базы данные Sitecore, но и допольнительные – в этом шаге осуществляется обновление этих баз данных посредством скриптов, сохраненных в сурс контроле в специальной папке, по аналогии с файлами из шагов 3 и 4. На данный момент, выбор нужного скрипта и применение его осуществляется при помощи специального формата имени файла (версия. имя). Если версия файлы выше чем версия базы данных (храниться в поле Extended properties) – база данных обновляется скриптом из файла. В скором времени, файлы для обновления базы данных будут доставаться приложением-сборщиком по аналогии с шагами 3 и 4. Также, в скором времени, планируется переключить этот шаг с исполнения на хосте билд сервера на исполнение на WCF сервисе (однако, в таком случае придется отказаться от App_Oflline.htm), что должно повысить безопасность.
- Собственно, доставка кода в приложение. Скрипт очищает папку с конфигами и бинарниками в приложении, затем, из распакованной в шаге 5 папки, доставляет код и сопутствующие файлы в папку веб-приложения. Последний шаг скрипта удаляет App_offline.htm.
- При помощи wget получаем страницу (как правило, главную) сайта, чтобы убедиться что приложение живо (код 200). Если код отличается от 200 – билд считается провалившимся.
Вот так функционирует автоматическая доставка веб-приложений, основанных на Sitecore CMS у нас.
Плюсы/минусы/нереализованные плюшки данного подхода
Собственно говоря, плюсов масса, но, главное что хотелось бы выделить – мы убрали из процесса доставки человека, со свойственной ему забывчивостью и просто ленью. Также, ввиду автоматизации – доставка значительно ускорилась. Конечно, в истоках все равно находиться человек (разработчик), и если он что то не закоммитил – оно не доставиться, или же заккомиттил неверно – тогда и доставиться неверно, но такие, чисто человеческие ошибки, как правило, отлавливаются еще на внутреннем тестировании.
Минусов, как и нереализованных плюшек, впрочем тоже хватает. Я хотел бы выделить несколько:
- Во все время билда необходимо чтобы интернет был подключен. Если возникла проблема с интернет подключением – то билд провалиться. Это не будет проблемой на шагах до пятого. Однако, если на 5ом шаге интернет отвалиться – приложение так и останется незапущенным, и починить можно будет только руками.
- Не вижу возможности реализовать автоматический откат на предыдущую версию в случае провала билда в шагах выше второго: бекап базы данных делается автоматически, но востановление его – довольно долгий процесс, а версионирование всех баз данных сайткора без сторонних (и довольно дорогих приложений) – невозможно. Также как и с базой данных – пока не представляю возможности автоматического отката кода.
- Нету 100% критерия, что доставка прошла успешно: бывают ситуации, когда проверочная страница возвращает код 200, в то время как другие могут валиться с ошибками.
- Доставка через SSH весьма хороша своей стабильностью и скоростью, но, в отличии от MS Publish Tool оставляет на целевом веб-приложении файлы, который были исключены из солюшена. Не то, чтобы это была крупная проблема – однако, просто некрасиво.
Автор: akuryan