Для ускорения и облегчения разработки наших проектов, использующих pull requests, я внедрил новую возможность на нашем билд сервере под управлением teamcity: автоматическая компиляция и тестирование каждого пулл реквеста и каждого изменения базовой ветки
Ранее, до внедрения этой фичи, у рецензента PR (здесь и далее - пулл запрос) было 2 возможных выхода (при условии отсутствия мерж конфликтов):
- Проверить код по диффам, и, если явных ошибок не видно - смержить автоматически и молиться, чтобы всё прошло удачно
- Склонировать в локальную ветку, проверить код, прогнать тесты и смержить, если всё хорошо.
Разумеется, подход 2 значительно лучше, чем подход 1, но он требует значительных затрат времени.
Естественно, всё, что требует значительных затрат времени на повторение одних и тех же процедур, можно автоматизировать. TeamCity позволяет нам это сделать :). Таким образом, процесс будет выглядеть так: при появлении PR, TeamCity автоматически запускает билд, состоящий из компиляции фронт- и бэк- энд кода и запуска тестов для HEAD этого PR. После мержа PR в базовую ветку - процесс повторяется, с тем, чтобы минимизировать вероятность возникновения мерж конфликтов.
Настройка TeamCity
Тут всё очень просто - необходимо лишь настроить Branch Specification для репозитория (я использую параметры, чтобы не плодить большого количества рутов системы контроля версий):
Параметр vcs.branch.specification можно задавать в несколько следующих значений:
- +:refs/pull/*/head
- +:refs/pull/*/merge
- +:refs/pull/(*/head)
- +:refs/pull/(*/merge)
Что это такое и как оно работает? Каждый раз, когда кто-либо создаёт PR, GitHub автоматические создаёт референс, в котором храниться и сам PR (head), так и его смерженное состояние с базовой веткой (merge). Таким образом, мы сообщаем TeamCity что он должен мониторить эти ветви, в дополнении к базовой. В данной записи, pull относиться к PR; * - означает любой PR; merge показывает, что мы хотим получать (клонировать) смерженый в базовую ветку результат; head - что мы хотим получать (клонировать) чистый, не смерженный PR; (*/head) или (*/merge) означают что помимо мониторинга PR, мы хотим получать уведомления и об изменениях базовой ветки.
Для себя я выбрал запись номер 3 (+:refs/pull/(*/head)) - это позволяет мне прогнать тесты на чистом PR, а после того, как его смержат в базовую ветку - прогнать тесты на результате, с тем, чтобы отловить возможные мержевые конфликты как можно раньше.
В итоге мы получим следующую картинку:
Как видно, TeamCity запускал наш тестовый билд несколько раз для раз PR, и лишь один раз он прошёл успешно (но, потом, провалился после мержа). Также, TeamCity добавляет фильтр, который позволяет нам выбрать лишь интересующие нас билды.
Далее, для автоматизации запуска билдов - нам необходимо определить триггер. Я использую обычный VCS trigger, настроенный как на скриншоте:
Он будет автоматически запускать тестовые билды, как только появиться PR или произойдёт изменения в базовой ветке.
Последняя фича, которую стоит настроить - это автоматическая публикация статуса наших тестов в PR. В TeamCity v.10 и далее она встроенна, для более ранних версий - опубликована как отдельный плагин тут - https://github.com/jonnyzzz/TeamCity.GitHub
Добавляется просто - идём в Build Features нашего билда и добавляем
Для Github'а этот плагин подерживает лишь обновление статусов в PR, но это то, что нужно. Конфигурация очень простая - можно использовать логин и пароль или Personal Access Token (его можно сгенерить тут - https://github.com/settings/tokens
Вот так Commit Status Publisher информирует о статусе проверочного билда в PR. Ссылка Details ведёт на лог билда. Всё просто, понятно и удобно, как мне кажется.