Преамбула
Какое-то время назад, решив навести порядок в нашем коде, выбрали в качестве системы контроля стиля кода 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.
![image](https://habrastorage.org/files/349/2a1/761/3492a176166142bbaefbe4f17a5305ee.jpg)
Естественно, это была оплошность из разряда «я все проверил, добавлю вот сюда одну строчку, она точно ничего не сломает». Код исправлен, релиз пересобран, ситуация исчерпана. Однако на следующий день ситуация повторилась с моим коллегой. В 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.
![image](https://habrastorage.org/files/d1f/f70/8e1/d1ff708e1a584d08884e53a26048fc06.png)
Отличие между checkstyle:check и checkstyle:checkstyle заключается в том, что первый зафейлит сборку, в случае нарушений, второй соберет весь проект и сформирует отчет по всем нарушениям.
Оптимальный способ — запустить первым шагом checkstyle:checkstyle, вторым уже chekstyle:check, который зафейлит сборку.
Добавляем commit status publisher
Далее к сборке, через Add build feature добавляется commit status publisher.
![image](https://habrastorage.org/files/989/6b5/12f/9896b512f33b45edbc115ae61649f9dc.png)
Настройки тривиальны — указываем адрес сервера gerrit, git-корень из которого собирается сборка, логин под которым будем ломиться в gerrit. Аутентификации в gerrit по открытому ключу, поэтому на сервере teamcity и агентах генерируем пару ключей, и регестрируем в gerrit.
Обеспечиваем запуск сборки
Осталось лишь настроить сборку таким образом, чтобы при появлении нового коммита на ревью сборка запускалась автоматом. Для этого в разделе Build triggers добавляем новый Branch Remote Run Trigger. Настраиваем его на ветку refs/changes/*.
![image](https://habrastorage.org/files/d92/474/518/d92474518e3d4014a981f62766b173f1.png)
Убеждаем teamcity что мы это мы
Ну и самое основное. Teamcity, используя Branch Remote Run Trigger запускает персональные сборки, а значит для того, чтобы сборка запустилась teamcity должен опознать в авторе комита своего пользователя. Для того, чтобы понять признал вас teamcity или нет — можете навести курсор на любой ваш коммит в истории сборок. Если вы видите текст TeamCity user: unknown — это значит, что потребуется еще одна настройка.
![image](https://habrastorage.org/files/e0e/148/33b/e0e14833b3c74eeb9df3216e0818b532.png)
В том же диалоге, есть строчка VCS username: — ее содержимое копируем и отправляемся в профиль пользователя teamcity. В разделе Version Control Username Settings записываем скопированное значение в «Default for all of the VCS roots:».
Публикуем отчеты
Еще один пункт — опциональный — вы можете настроить в teamcity build feature под названием «XML report processing», для того, чтобы teamcity парсил логи checkstyle и показывал нарушения стилей в результатах сборки. Пример настроек ниже.
![image](https://habrastorage.org/files/689/82f/4ef/68982f4ef8844440977e1ddcbe2a4eef.png)
После этих настроек можно попытаться отправить код на ревью в геррит. В течение некоторого времени должна запуститься сборка, которая по результатам проставит +1 или -1 в геррит. Если время прошло, а сборка так и не запустилась — причину искать в логе teamcity.
Описанным мной способом можно также контролировать выполнение unit-тестов для каждого коммита.