Преамбула
Какое-то время назад, решив навести порядок в нашем коде, выбрали в качестве системы контроля стиля кода Checkstyle. Думаю, проект знакомый, в представлении не нуждается. До этого в команде мы использовали общий репозиторий, где хранились настройки code styles, intentions для идеи.
Добавляя в проект checkstyle, мы в первую очередь преследовали цель — возможность превратить ошибки в оформлении стиля кода в ошибки сборки. Лёгким движением руки checkstyle был подключен в корневой pom проекта, разработчики были ознакомлены с нововведением, сборки на Teamcity научились проверять checkstyle перед коммитом.
Да вот незадача: в наших рядах появился вредитель. Как мы с ним боролись — под катом.
Вредоносное изменение было замечено сразу же, при сборке очередного релиза. Сборка упала с сообщением:
[ERROR] Habr.java[31:1] (imports) IllegalImport: Import from illegal package - org.apache.commons.lang
[ERROR] Habr.java[32:1] (imports) IllegalImport: Import from illegal package - org.apache.commons.lang
Ага, подумал я, сейчас я тебя вычислю. И взялся за git blame. Нарушитель был вычислен быстро. Каково же было мое удивление, когда выяснилось что нарушитель — я. Но ведь я собрал проект перед комитом, прогнал checkstyle.
Естественно, это была оплошность из разряда «я все проверил, добавлю вот сюда одну строчку, она точно ничего не сломает». Код исправлен, релиз пересобран, ситуация исчерпана. Однако на следующий день ситуация повторилась с моим коллегой. В Intelij Idea есть отличная опция «Reformat code», которая может быть включена в диалоге коммита. Её советую всем своим коллегам, собираясь забыть об этой проблеме раз и навсегда, но вот опять — сборка не собирается, в логе:
[ERROR] Habr.java[136:27] (whitespace) WhitespaceAround: 'if' is not followed by whitespace.
Конечно, кто-то забыл включить эту опцию, кто-то проигнорировал это письмо. Но вернемся к началу разговора — мы ведь собирались использовать checkstyle, чтобы ошибки в оформлении кода перенести на этап сборки — но ведь не обязательно переносить их на этап сборки патча.
Teamcity+gerrit в помощь
У нас в компании уже несколько лет используется gerrit для проведения code-review на проекте. Почему-бы не скрестить code review с checkstyle. Вооружившись гуглом и желанием раз и навсегда решить проблему кривых стилей взялся за настройку этого хозяйства. Неудачный опыт опущу, опишу работающий по сей день вариант интеграции.
В работе будем использовать commit status publisher плагин, teamcity, gerrit.
Сам плагин включен в состав teamcity начиная с версии 7.1 (если ничего не путаю).
Настраиваем запуск checkstyle
Первым делом создаем билдплан, в котором одним из шагов мы должны выполнить checkstyle.
Отличие между checkstyle:check и checkstyle:checkstyle заключается в том, что первый зафейлит сборку, в случае нарушений, второй соберет весь проект и сформирует отчет по всем нарушениям.
Оптимальный способ — запустить первым шагом checkstyle:checkstyle, вторым уже chekstyle:check, который зафейлит сборку.
Добавляем commit status publisher
Далее к сборке, через Add build feature добавляется commit status publisher.
Настройки тривиальны — указываем адрес сервера gerrit, git-корень из которого собирается сборка, логин под которым будем ломиться в gerrit. Аутентификации в gerrit по открытому ключу, поэтому на сервере teamcity и агентах генерируем пару ключей, и регестрируем в gerrit.
Обеспечиваем запуск сборки
Осталось лишь настроить сборку таким образом, чтобы при появлении нового коммита на ревью сборка запускалась автоматом. Для этого в разделе Build triggers добавляем новый Branch Remote Run Trigger. Настраиваем его на ветку refs/changes/*.
Убеждаем teamcity что мы это мы
Ну и самое основное. Teamcity, используя Branch Remote Run Trigger запускает персональные сборки, а значит для того, чтобы сборка запустилась teamcity должен опознать в авторе комита своего пользователя. Для того, чтобы понять признал вас teamcity или нет — можете навести курсор на любой ваш коммит в истории сборок. Если вы видите текст TeamCity user: unknown — это значит, что потребуется еще одна настройка.
В том же диалоге, есть строчка VCS username: — ее содержимое копируем и отправляемся в профиль пользователя teamcity. В разделе Version Control Username Settings записываем скопированное значение в «Default for all of the VCS roots:».
Публикуем отчеты
Еще один пункт — опциональный — вы можете настроить в teamcity build feature под названием «XML report processing», для того, чтобы teamcity парсил логи checkstyle и показывал нарушения стилей в результатах сборки. Пример настроек ниже.
После этих настроек можно попытаться отправить код на ревью в геррит. В течение некоторого времени должна запуститься сборка, которая по результатам проставит +1 или -1 в геррит. Если время прошло, а сборка так и не запустилась — причину искать в логе teamcity.
Описанным мной способом можно также контролировать выполнение unit-тестов для каждого коммита.