Jenkins + PHP по-русски: непрерывная интеграция для php-проектов

Jenkins? Сборка? PHP? – спросите вы и сделаете удивлённые глаза О_о. Какое отношение сборка проектов, естественная для большинства компилируемых языков типа C или Java, имеет отношение к проектам на PHP? Они же не компилируются и не “собираются”.

Когда я искал материалы по непрерывной интеграции (continuous integration), мне так и не удалось найти ни одной простой статьи, где простым русским языком объяснялось бы – зачем (нафига) всё это надо применительно к PHP. Поэтому в посте я расскажу, во-первых, что к чему, а во-вторых – как это использовать в повседневной жизни.

Кому предназначен этот пост:

Разработчикам, лидерам команд и менеджерам проектов, которые доросли до мысли что поставка новых версий программного продукта (даже на PHP) должна быть стабильной и регулярной, как на конвейере японского завода. Желательно, чтобы слова “автоматизированное тестирование” и “деплой” были для вас не пустым звуком. Ну или хотя бы вы заинтересованы в том, как (чёрт побери) перестать выкладывать “бажные” обновления.

Также пост может быть полезен командам, во главе которых стоит типичный маркетоид или иной гуманитарий, и они вынуждены хотя бы внутри себя контролировать качество кода.

Поскольку мне хочется написать обзорный пост, а не пошаговую инструкцию для чайников, сначала несколько базовых понятий на примере Ubuntu Server:

sudo apt-cache search – поиск пакета name;
sudo apt-get install – установка пакета name;
pear list -a – список установленных пакетов PEAR;
pear config-set auto-discover 1 – автодискавер каналов PEAR (удобно, чтоб не добавлять эти каналы ручками);
pear install –alldeps – установка PEAR-овского пакета name со всеми зависимостями.

Теория:

Никакой сборки, в общем случае, в PHP-проектах нет. Поэтому забудьте слово “сборка”, и думайте о наборе каких-то важных процедур, которые стоит проходить регулярно по расписанию или перед очередным релизом проекта. Это может быть выкладывание новой версии продукта или обновление сайта, или какое-то иное событие.

Суть в том, что вы изо дня в день коммитите, коммитите, коммитите изменения, и периодически вам хочется проверять – а не сломалось ли чего? А работают ли все бизнес-функции? А не накосячил ли новый сотрудник? А тот лентяй в углу наконец-то научился правильно применять кэмэл-кейс в наименованиях и ставить принятые в команде отступы и скобочки? А не растёт ли у нас объём “мертвого” кода, который уже нигде не используется? А как насчёт бездумного копипаста, избыточных классов, неиспользуемых переменных?

Причём как любому нормальному лентяю – вам хочется проводить всё это автоматически. А если что-то не так – то и вам и конкретному виновнику надо получать репорт. Итак, предположим что у вас есть некий сервер с линуксом на борту, где есть веб-окружение и где вы уже умеете разворачивать проект из svn/git/итд.

Инструменты:

Jenkins – написанный на адском Java, со страшным GUI, адски тормозящий “сервер” непрерывной интеграции. Смысла в нём почти никакого, кроме того что он – готовый базис для перечисленных задач. Сам он почти ничего не умеет, а только рулит сторонними процессами и плагинами. Как будет понятно дальше – это нам и надо.

Ant – скромная программа для выполнения набора шелл-команд в линуксе. От простого sh-файла отличается несколькими полезными плюшками типа удобного синтаксиса для манипуляции с файлами и каталогами, очередностью и зависимостями выполнения задач и прочими мелочами. Конфигурируется в простом xml-файлике, ничего сложного. Применяется для последовательного запуска перечисленных ниже инструментов. Также может применяться для “подчистки” временных файлов, сборки документации (PHPDoc), компрессии CSS/JS-файлов и любых других задач.

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

PHP CodeSniffer – пакет PEAR, который следит за соблюдением стандартов кодирования (отступы, длины строк, наименования переменных и так далее). Можно использовать готовые стандарты или написать свои. Если у вас в команде каждый день бушуют холивары типа “4 пробела против табуляции” или “отделять ли пробелами точку в конкатенации строк” – самое то.

PHP Mess Detector – один из самых полезных пакетов PEAR в этой подборке. Следит за качеством кода с точки зрения кода (а не его стиля написания). Например, упрекнёт вас, если у вас слишком много паблик-методов в классе. В общем, подскажет где вас ждёт рефакторинг.

PHP Copy/Paste Detector – как понятно из названия, пакет PEAR для отслеживания копипаста. Бездумно не копипастить, помните?

PHP Dead Code Detector – очередной пакет PEAR с говорящим названием. Находит неиспользуемые участки кода. Кстати, единственный пакет, который мне не удалось прикрутить к Jenkins-у (если знаете как – welcome в комментарии).

PHP Depend – самый адски непонятный пакет PEAR, который строит сложные графики и “пирамиды” зависимостей, наследуемостей, и много чего ещё. Стоит применять, если со всем остальным вы уже разобрались.

А так же вам надо установить набор плагинов для связки Jenkins-PHP по образцу с сайта jenkins-php.org (руками через админку ставить – возни на час, поэтому воспользуйтесь готовыми командами из абзаца “using Jenkins CLI”).

Как завести всё это вместе:

Итак, вы взяли отдельный линукс-сервер и установили туда всё это хозяйство. Сначала вам нужно определиться с рабочей директорией. Будет удобно, если это будет каталог выше уровнем относительно того, куда разворачивается ваш проект из системы контроля версий.

Теперь вам нужно настроить Ant, а именно составить для него конфигурационный файл build.xml в рабочей директории, которую вы определили абзацем выше. По Ant-у есть отличные доки, гуглите и берите примеры. Лично у меня Ant используется для прогонки тестов и всех вышеперечисленных анализаторов. Результаты их работы складываются в специальную поддиректорию.

Затем нужно создать проект (задачу) в Jenkins. На это тоже есть готовые доки, отмечу несколько важных моментов:

– проверьте, что в настройках проекта используется корректная базовая директория, потому что относительно неё будут указываться пути к файлам-результатам;
– настройте апдейт из системы контроля версий;
– в разделе “Post-build Actions” подключите плагины: PMD, Checkstyle, Duplicate code, Coverage (Clover), JDepend, и другие на свой вкус.

Что должно получиться в результате:

По нажатию “Собрать сейчас” должен запускаться процесс сборки. Найдите пункт с названием типа “Смотреть консоль” (перевод хромает, да) – и там вы увидите весь лог происходящего. Например, шаги могут быть такими:

– апдейт из системы контроля версий;
– запуск Ant, который внутри себя запустит phpunit, phpmd, phpcs и прочее;
– парсинг результатов, заданный вами в post-build actions.

В результате вы получите кучу различной статистики о том, что происходит в вашем проекте на момент этой “сборки”. Не только результаты тестов, но и результаты вышеперечисленных анализаторов. Jenkins показывает её в относительно удобочитаемом виде прямо в браузере.

Примерно так выглядит сводная страница проекта:

Продолжение (с картинками и советами) следует, подпишитесь на RSS.