Перейти к содержимому

Автоматическая компиляция пулл-реквестов

Для ускорения и облегчения разработки наших проектов, использующих pull requests, я внедрил новую возможность на нашем билд сервере под управлением : автоматическая компиляция и тестирование каждого пулл реквеста и каждого изменения базовой ветки

Ранее, до внедрения этой фичи, у рецензента PR (здесь и далее - пулл запрос) было 2 возможных выхода (при условии отсутствия мерж конфликтов):

  1. Проверить код по диффам, и, если явных ошибок не видно - смержить автоматически и молиться, чтобы всё прошло удачно
  2. Склонировать в локальную ветку, проверить код, прогнать тесты и смержить, если всё хорошо.

Разумеется, подход 2 значительно лучше, чем подход 1, но он требует значительных затрат времени.

Естественно, всё, что требует значительных затрат времени на повторение одних и тех же процедур, можно автоматизировать. TeamCity позволяет нам это сделать :). Таким образом, процесс будет выглядеть так: при появлении PR, TeamCity автоматически запускает билд, состоящий из компиляции фронт- и бэк- энд кода и запуска тестов для HEAD этого PR. После мержа PR в базовую ветку - процесс повторяется, с тем, чтобы минимизировать вероятность возникновения мерж конфликтов.

Настройка TeamCity

Тут всё очень просто - необходимо лишь настроить Branch Specification для репозитория (я использую параметры, чтобы не плодить большого количества рутов системы контроля версий):

vcs_root

Параметр vcs.branch.specification можно задавать в несколько следующих значений:

  1. +:refs/pull/*/head
  2. +:refs/pull/*/merge
  3. +:refs/pull/(*/head)
  4. +:refs/pull/(*/merge)

Что это такое и как оно работает? Каждый раз, когда кто-либо создаёт PR, GitHub автоматические создаёт референс, в котором храниться и сам PR (head), так и его смерженное состояние с базовой веткой (merge). Таким образом, мы сообщаем TeamCity что он должен мониторить эти ветви, в дополнении к базовой. В данной записи, pull относиться к PR; * - означает любой PR; merge показывает, что мы хотим получать (клонировать) смерженый в базовую ветку результат; head - что мы хотим получать (клонировать) чистый, не смерженный PR; (*/head) или (*/merge) означают что помимо мониторинга PR, мы хотим получать уведомления и об изменениях базовой ветки.

Для себя я выбрал запись номер 3 (+:refs/pull/(*/head)) - это позволяет мне прогнать тесты на чистом PR, а после того, как его смержат в базовую ветку - прогнать тесты на результате, с тем, чтобы отловить возможные мержевые конфликты как можно раньше.

В итоге мы получим следующую картинку:

results

Как видно, TeamCity запускал наш тестовый билд несколько раз для раз PR, и лишь один раз он прошёл успешно (но, потом, провалился после мержа). Также, TeamCity добавляет фильтр, который позволяет нам выбрать лишь интересующие нас билды.

Далее, для автоматизации запуска билдов - нам необходимо определить триггер. Я использую обычный VCS trigger, настроенный как на скриншоте:

vsc_trigger

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

Последняя фича, которую стоит настроить - это автоматическая публикация статуса наших тестов в PR. В TeamCity v.10 и далее она встроенна, для более ранних версий - опубликована как отдельный плагин тут - https://github.com/jonnyzzz/TeamCity.GitHub

Добавляется просто - идём в Build Features нашего билда и добавляем
commit-status-publisher-featureДля Github'а этот плагин подерживает лишь обновление статусов в PR, но это то, что нужно. Конфигурация очень простая - можно использовать логин и пароль или Personal Access Token (его можно сгенерить тут - https://github.com/settings/tokens

build-ok build-failed build-runningВот так Commit Status Publisher информирует о статусе проверочного билда в PR. Ссылка Details ведёт на лог билда. Всё просто, понятно и удобно, как мне кажется.