Выгрузка кода с использованием webhook в Bitbucket

Ильдар Сарибжанов | 20.02.2017

Вступление

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

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

Сразу признаюсь, что решение придумал не сам, все уже где-то есть, я просто собрал все в единое целое.

К делу

Не буду мусолить и рассказывать, как быстро нашел способ автоматизации. Перейдем непосредственно к описанию.

Необходимые условия для того, чтобы решение работало:

  1. Удаленный репозиторий лежит на битбакет (конкретно для этого случая, выше сказал, что можно приделать и к github при желании)
  2. На боевом сервере есть Git.

Несоблюдение любого из условий, приведет к краху затеи.

У битбакета есть сервис, называемый webhook. Он из себя представляет следующее: на стороне битбакета настраивается адрес, куда будут отправляться пакеты данных при выполнении некоторых событий (срабатываение триггера), определяемых настройкой Triggers

Мне достаточно было выбрать первый параметр (отмечен стрелкой), без расширенных настроек. Из обязательного тут еще поле url — это адрес, куда будут уходить пакеты, лучше какую-нибудь поддиректорию, которая будет исключена из индекса, чтобы не загаживать корень проекта. Не люблю, когда не убрано.

Так как же оно работает? Когда срабатывает триггер, сервер отправляет пакет данных на указанный адрес, и со стороны сервера можно делать что угодно, отправлять email, запускать кофемашину, или проигрывать фанфары, но значительно удобнее и логичнее выполнять простенькую команду git pull.

Отлично! Битбакет настроен. Чего дальше? А дальше моя любимая часть!

Идем вот по этому адресу, а лучше не идем, а сразу клонируем на сервер =). Разворачивать нужно в ту папку, которая ответит по адресу, который указан в url, чтобы запросы обрабатывались.

И что мы видим? 5 файлов, один из которых gitignore, еще один пример конфига.

Еще раз проговорю: нужно чтобы url, настроенный в webhook, смотрел на index.php, это важно!

Далее нужно создать свой config.php, или переименовать config.php.example, и сконфигурировать его:

$bitbucket_IP_ranges = array(
	'131.103.20.160/27',
	'165.254.145.0/26',
	'104.192.143.0/24'
);

$need_branch = 'master';

$log_file = '/var/logs/deploy.log';

$path_repo = '/path/to/your/project';

Настройки незамысловаты и в большинстве случаев потребуют изменить только последний параметр.

$bitbucket_IP_ranges — это ip’шники bitbucket. На всякий случай их чекаем, чтобы быть уверенным, что запрос пришел откуда надо.
$need_branch — казалось бы зачем указывать нужную ветку. А вот тут проявляются особенности настроек webhook. Триггер будет отправлять запрос при каждом (!) пуше. Т.е. ветки dev/feature/bugfix и другие, будут инициировать отправку пакета на сервер. Этим параметром, уже на стороне боевого сервера сообщаем, что нужно реагировать только на указанную ветку.
$log_file — логи это хорошо, нужно больше логов!
$path_repo — тебе точно нужно описание этого параметра? На всякий случай, это папка проекта, где расположен git репозиторий.

Сам класс deploy.php выполняет нехитрые действия: из под php запускает 2 команды

git reset --hard HEAD
git pull origin [need_branch]

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

Теперь кажется всё готово, отправляем тестовый пуш в мастер ветку, и смотрим на изменения на сервере. Та-дан! Не забывайте про кэширование, которое может не отобразить изменения.

Итог

Я стал на шаг ближе к идеальному производственному процессу. Можно сказать, сделал небольшой вклад в OpenSource. Конечно, подобный велосипед не дорого стоит, и запилить его можно за полчаса левой пяткой, если знать что делать. Теперь и ты знаешь ;)

Всем рок!