Хочу рассказать вам об облачном сервисе CI/CD под названием Bitbucket Pipelines, которым я последнее время активно пользуюсь.
Первая публичная бета была объявлена весной 2016 года, а летом 2017 сервис вышел из беты в так сказать production режим.
Я же начал пробовать лишь в конце 2017 года, так что имею опыт всего в несколько месяцев.
Итак, Bitbucket Pipelines — в первую очередь это Continues Integration сервис, хорошо интегрированный с хранилищем репозиториев Bitbucket.
Как сейчас принято во всех модных CI системах, мы добавляем в корень репозитория специальный файл, в данном случае bitbucket-pipelines.yml, и дальше на каждый push отправленный в Bitbucket запускаются задачи, описанные в этом файле. Запуск происходит целиком и полностью на серверной инфраструктуре Bitbucket внутри Docker контейнеров, нам не нужно иметь свои собственные серверы агенты или воркеры.
Причём в качестве базового образа можно использовать любой Docker образ (для сравнения, на сколько я помню в Travis выбор ограничен заранее подготовленным набором контейнеров). У меня есть несколько образов собственного приготовления со всеми необходимыми версиями языков, расширений и сторонними утилитами внутри.
Файл bitbucket-pipelines.yml выглядит достаточно типично и привычно (если сравнивать с тем же Travis’ом или GitLab’ом): сущность самого верхнего уровня — это pipeline. У нас может быть несколько разных пайплайнов привязанных к разным веткам или тегам исходного кода. Причём можно указывать маски glob patterns для имён веток и тегов.
Далее внутри пайплайна идёт набор steps (шагов). Шаги выполняются последовательно, если какой-то шаг завершился с ошибкой, то последующие не выполняются. Step можно определить, как запускаемый исключительно вручную — удобно для реализации деплоя по кнопке. Каждый Step начинается с чистого листа — это новый Docker контейнер в котором автоматически доступны исходники нашего приложения. Есть возможность передавать артефакты между шагами.
Внутри Step мы описываем tasks (задачи). task это по сути консольная команда — например, сначала я делаю composer install, затем codecept run.
Чтобы не качать composer пакеты из дикого интернета каждый раз, сервис предоставляет механизм кеширования. Из коробки есть заготовки для composer, для npm и ещё каких-то пакетных менеджеров, но можно описать и свои правила, какую именно директорию кешировать.
Я сейчас специально не углубляюсь в детали, как оно там под капотом работает, как инвалидируется кэш и т.п.
А что, если для запуска тестов нужна база данных (типа MySQL или PostrgreSQL) и ещё какой-нибудь кеширующий слой (Memcache или Redis) — в терминах Bitbucket Pipelines это «сервисы». Вместе с запуском основного контейнера с тестами мы можем запустить до пяти дополнительных сервисов, которые также являются запущенными Docker контейнерами доступными по сети по их именам.
Более того, один из возможных сервисов — это Docker демон для построения наших собственных образов внутри пайплайна, который потом можно отправить на Docker Hub или в собственный приватный репозиторий.
Объём оперативной памяти ограничен 4Гб на всё — основной контейнер + все доп. сервисы. Есть возможность запускать контейнеры с удвоенным объёмом памяти, указав специальную опцию в yml файле size: 2x
Секретные данные (ключи, пароли) можно прокинуть внутрь окружения, в котором запускаются наши задачи в виде переменных окружения, предварительно добавив их через веб-интерфейс Bitbucket.
Bitbucket славен своими бесплатными приватными репозиториями, при условии, что команда до 5-ти человек. Так вот запуск пайпланов для приватных репозиториев также бесплатный, но в рамках 50 минут в месяц. И это на самом деле маловато. Даже если ограничиться лишь ежедневными ночными сборками по расписанию (т.е. не делать запуск на каждый push), выходит 30 запусков в месяц — на каждый меньше двух минут. Как показала практика, разворачивание основного контейнера + контейнера с MariaDB + клонирование репозитория и распаковка composer кеша уже сами по себе занимаются минимум 1-2 минуты, а изредка всё подвисает на 5-10 минут.
Далее идёт платный тарифный план: 1000 минут за $10 в месяц, и вот это мне уже нравится. Я настроил несколько своих PHP проектов и за первый месяц использовал всего 300 минут. Тогда я перевёл сборку всех докер образов на Bitbucket Pipelines и ещё немного увеличил утилизацию.
Из неудобного — синтаксис bitbucket-pipelines.yml не позволяет переиспользовать какие-то собственные фрагменты. Например, я описал pipeline для ветки master, состоящий из пары шагов (steps), внутри которых пара десятков задач (tasks). Теперь я хочу описать похожий pipeline для ветки staging — первый шаг аналогичен, а второй отличается. Приходится копипастить.
Для отладки пайплайнов прочитал на форуме про какой-то python скрипт, но я не пробовал, отлаживал на живую и это выходит не очень быстро. Что немного смягчает проблему: есть online валидатор для файла bitbucket-pipelines.yml и он проверяет не только отступы, но и внутреннюю логику и правильность написания тех или иных параметров.
Нет системы матричного запуска, когда, например, нужно прогнать тесты на разных версиях PHP или разных версиях базы данных — каждый раз приходится копировать описание всего pipeline, меняя лишь тег Docker образа. Для создателей библиотек или коробочных продуктов это будет настоящий ад. Но если тестируем какой-то внутренний продукт, который должен работать на конкретной версии PHP, проблема исчезает.
Внутри веб-интерфейса Bitbucket запуск пайплайнов и просмотр результатов отлично интегрирован с репозиториями. Есть интеграции с Slack, HipChat и другими сервисами. Более того, в GUI клиенте для Git и Mercurial под названием SourceTree (которым владеет та же компания Atlassian) напротив каждого коммита отображается статус билда. Плюс SourceTree умеет выводить системные уведомления, если билд завершился с ошибкой.
Лично для меня Bitbucket Pipelines отлично подошел по нескольким причинам:
— У меня не сложные конфигурации, мне не нужны крутые возможности Jenkins или TeamCity
— Я не люблю ничего хостить сам. Пусть даже запуск воркеров того-же GitLab настраивается элементарно, но, если вообще ничего не нужно делать на своей инфраструктуре — для меня это большой плюс.
— Поскольку все мои репозитории итак уже на Bitbucket, приятно иметь хорошо интегрированную систему CI
— В некоторых проектах я всё ещё использую Mercurial и Bitbucket Pipelines отлично с ним работает — умеет клонировать Mercurial репозиторий, умеет фильтровать нужные pipelines для запуска по bookmarks
— $10 в месяц за 1000 минут — это одновременно и очень дешево и вполне достаточно!
Если у вас ещё не настроены CI процессы и к тому же, вы храните репозитории на Bitbucket, попробуйте Bitbucket Pipelines — порог входа очень низкий!
Если у вас уже есть свой CI сервер, но он отнимает у вас слишком много сил и времени на поддержку, обновления и т.п., то Bitbucket Pipelines опять же не плохой вариант, чтобы избавиться от головной боли.
Естественно, сервис Bitbucket Pipelines не один такой, из самых знаменитых в этой нише: Travis и Circle CI.
А не так давно в подкасте Разбор полётов услышал про некий свежий проект Cirrus CI — и он мне показался интересным. Возможно, это будет следующий облачный CI сервис, который я попробую, когда упрусь в какие-то ограничения Bitbucket Pipelines.
Поскольку я записываю пятиминутку PHP раз в полгода, чтобы вы не скучали, дам ещё ссылку на подкаст Радио-Т выпуск 497 от 28 мая 2016 года — там на 32 минуте начинается обсуждение только что анонсированного сервиса Bitbucket Pipelines. Умпутун говорит, что это будет буквально революция, но спустя почти два года я не вижу никакой революции или хайпа вокруг Bitbucket Pipelines, весь хайп последние годы вокруг GitLab.
Ещё один интересный ресурс — это регулярные виде-встречи сообщества Hangops.ru. Записи можно посмотреть на YouTube, некоторые из них дублируются и в форме подкаста. Дам ссылку на запись от 1-го февраля 2018 года с темой «Что такое Continuous Integration (CI/CD) и где его взять?» — обсуждение не спешное, о концепциях, а не о конкретных технологиях и, подходит для просмотра, когда есть тихий свободный вечер.