Использование gitlab continuous integration для деплоя
Совсем недавно гитлаб героически выкатил версию 8.0 своего конкурента гитхабу. Из интересного — движок continuous integration теперь встроен в платформу, а значит доступен в качестве бесплатного сервиса для всех желающих на gitlab.com. Совместно с бесплатными приватными репозиториями это делает облачный сервис гитлаб не только удобным местом для хранения кода, но также тестирования и деплоя. О последнем я и расскажу под катом.
Continuous integration — это не только запуск юнит тестов при пуше нового кода в репозиторий. Это еще и возможность делать сборки продуктов, публиковать их в сторы, на сайты и в другие каналы распространения. Облачная телефония voximplant использует javascript сценарии, которые размещаются в нашем облаке и выполняются по команде “снаружи” или при поступлении входящего звонка. Многие клиенты для работы со сценариями используют встроенный в админку текстовый редактор, что вполне подходит для простых случаев. Но при разработке и поддержке сложных облачных систем, к примеру телефонии Bitrix24, нужно что-то более серьезное.
Создавая voximplant мы решили не делать push-to-deploy как у heroku. У многих наших клиентов основной бизнес не связан с разработкой софта, и оставлять их один на один с git’ом не очень хорошо. Зато есть HTTP API с функцией “задеплоить сценарий”, который намекает понимающим людям что сценарии можно хранить на gitlab и деплоить с помощью shell скрипта и curl. Большинство клиентов так и делает, но у подхода есть серьезный недостаток: скрипт нужно не забыть вызвать. Более того, вызывать его надо только если код был запушен в production ветку. И только после того, как прошли тесты. Вообще много способов ошибиться.
По умолчанию continuous integration в гитлабе выключено и необходимо его включить в настройках:
После включения в левом меню настроек проекта появляется несколько новых пунктов, самый интересный для нас — это «runners». Continuous integration в гитлабе работает следующим образом:
- Вы делаете push в репозиторий
- Если в корне проекта есть файл .gitlab-ci.yml, то гитлаб понимает что для этого проекта будет использоваться continuous integration.
- Гитлаб ищет запущенный runner, подключенный для этого или для любого проекта. Runner — это приложение, которое обычно запускают на отдельном компьютере и которое будет собственно осуществлять continuous integration: прогонять тесты, собирать исполняемые файлы, осущестлять деплой. Можно запустить свой runner, к примеру на маке чтобы собрать приложение для iOS. Можно использовать “gitlab public runner”, но они не то чтобы очень безопасны и входящие очереди задач у них обычно многочасовые.
- Гитлаб передает yaml файл runner’у, который обновляет исходники в своем репозитории и выполняет команды, описанные в этом файле. Команды могут быть как простые, к примеру сделать деплой сценария в облако voximplant. Так и сложные: запуск docker контейнера, сборка в нем проекта, запуск тестов и так далее.
- После выполнения скриптов runner рапортует обратно гитлабу резулттаты, которые можно посмотреть рядом с соответствующим коммитом.
Для нашего примера мы запустим runner на машине разработчика. Инструкции по установки для windows/linux/osx доступна на официальном сайте, после установки мы получаем в свое распоряжение command line утилиту gitlab-ci-multi-runner. Запущенный runner подключается к гитлабу и ждет задачи на сборку. Но как гитлаб узнает, какие задачи какому runner’у давать? Чтобы “привязать” runner к своему аккаунту и проекту (или нескольким проектам) необходимо вызвать gitlab-ci-multi-runner с ключем register и ввести параметры подключение: url гитлаб (так как гитлаб может быть развернут локально в вашей сети) и токен регистрации, который, собственно, и определяет аккаунт/проекты:
Зарегистрированный runner запускается командой gitlab-ci-multi-runner run и ждет задачу от гитлаба. С помощью ключей командной строки install и start runner можно зарегистрировать в системе как сервис, чтобы он автоматически стартовал после перезагрузки операционной системы.
Как я уже писал, задачи continuous integration описываются в файле .gitlab-ci.yml который необходимо разместить в корне проекта. Редкоземельный синтаксис YAML является как-бы-человекочитаемой альтернативой JSON’у, документация доступна на официальном сайте. Конфигурационный файл для деплоя проекта в voximplant будет максимально простым, все что нам нужно — это сделать один вызов HTTP API как описано в нашей документации. Если исходить из предположения, что runner выполняется на компьютере где установлен curl, а код сценария находится в файле scenario.js, то конфигурационный файл для деплоя будет выглядеть следующим образом:
before_script:
- npm install
stages:
- deploy
deploy:
script:
- curl -X POST "https://api.voximplant.com/platform_api/SetScenarioInfo/?account_id=1&api_key=2&required_scenario_name=foo" --data-urlencode scenario_script@scenario.js
В curl используется синтаксический сахар нашего API, которое может принимать аргументы как в компоненте query передаваемого url, так и в body http запроса.
Чтобы continuous integration заработал достаточно сделать push в репозиторий: гитлаб обнаружит файл .gitlab-ci.yml, найдет подключенный runner, передаст ему содержимое этого файла, runner обновит свою копию репозитория и запустит скрипт деплоя, который отгрузит исходный код в наше облако.
Вопросы, уточнения, комментарии? Gitlab vs Jenkins vs Bamboo vs Teamcity?