CruiseControl (CC) и Continuous Integration (CI)
Опубликовано: 28.05.2010
|
1. Введение
CI - continuous integration (непрерывная интеграция) - это методика разработки проекта , которая определяет процесс разработки ПО, как неразрывную цепочку повторяющихся действий по разработке и внедрению. Основа подхода continuous integration направлена на нивелирование проблем связанных с интеграции Вашего программного продукта на сервер заказчика, а также бонусом этого является то, что это обеспечивает рабочий проект в любой момент времени, готовый к развертыванию (deployment) на production сервер. Неотъемлемой частью continuous integration, является приемочное тестирование, юнит тестирование, функциональное тестирование, в автоматическом режиме, как метод контроля корректности работы Вашего приложения после изменений.
Подробно можно прочесть по следующим ссылкам:
http://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%BD%D0%B0%D1%8F_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F
http://en.wikipedia.org/wiki/Continuous_integration
http://martinfowler.com/articles/continuousIntegration.html
Если рассматривать шаги, которые нужны для развертывания (deployment), можно выделить основное:
- Получение исходников из репозитория;
- Сборка проекта;
- Тестирование;
- Развертывание;
- Сбор статистики.
Также крайне охота иметь следующие события для проверки сборки
- При обновлении кода в репозитории;
- По расписанию;
- Принудительно, скажем перед релизом.
Собственно, в статье ниже приведен полный мануал по установке и настройке среды для запуска CI. В качестве оболочки был выбран CruiseControl с расширением phpUnderControl.
Основные задачи которые решает CruiseControl:
- Мониторинг репозитория и/или файловой системы на предмет изменений для запуска процесса сборки
- Сборка по расписанию и принудительно
- Уведомление о результатах сборки по email/jabber/other messengers/sms
- Создание отчетов по сборке, что собралось, что не собралось, почему и т.д.
- Создание статистических отчетов
- Удачных билдов vs заваленных
- Покрытия кода тестами, документаций etc.
- Количество методов, строк, файлов, классов etc.
- Время затраченное на сборку
- Создание документации по проекту/Api
- Выявление ошибок в коде, copy/paste etc.
- Прогон тестов и сбор статистики по этому, с возможностью просмотра информации по каждому билду
- Контроль стандартов кодирования принятых в компании (предполагается Zend)
- Браузинг по исходникам
- История билдов
Тесть практически, решение всех насущных проблем которые возникают при разработке ПО. Также позволяет держать проекты под контролем и мониторить текущее состояние. Ну, что ж попробуем все это поставить и поднять свой уровень разработки на качественно новый уровень.
2. Установка
Установка СС на Linux , предполагается что у Вас предварительно установлен git && java 1.6. Если нет, тогда
# apt-get install git
# apt-get install sun-java6-bin ia32-sun-java6-bin
CruiseControl
Итак приступим, для начала скачаем последнюю версию СС и распакуем ее в /opt/
# cd /opt/
# wget http://downloads.sourceforge.net/project/cruisecontrol/CruiseControl/2.8.3/cruisecontrol-bin-2.8.3.zip?use_mirror=heanet
# unzip cruisecontrol-bin-2.8.3.zip
# mv cruisecontrol-bin-2.8.3 cruisecontrol
phpUnderControl
Скачиваем и устанавливаем плагин phpUnderControl
# cd /opt/
# git clone git://github.com/manuelpichler/phpUnderControl.git
# cd phpUnderControl/bin/
# chmod +x phpuc.php
# nano phpuc.php
И меняем первую строку на #!/usr/bin/php после чего сохраняем. Запускаем установку плагина.
# ./phpuc.php install /opt/cruisecontrol
phpUnderControl расширения
phpUnderConrtol metrics
Скачиваем и распаковываем ezComponents, они нам понадобятся для отображения графиков.
# cd /opt/phpUnderControl/lib
# wget http://ezcomponents.org/files/downloads/ezcomponents-2009.2.tar.bz2
# tar -xvf ezcomponents-2009.2.tar.bz2
# cp -R ezcomponents-2009.2 ezc
phpunit
Простой путь установки phpunit, это используя apt.sources
# sudo apt-get install phpunit
Но также можно установить руками, предполагается прямыми :) . Подробнее по ссылке http://www.phpunit.de/manual/current/en/installation.html
# pear channel-discover pear.phpunit.de
# pear channel-discover pear.symfony-project.com
# pear install phpunit/PHPUnit
# phpunit --version
PHPUnit 3.3.16 by Sebastian Bergmann.
Ну и собственно если все работает, идем дальше ... to be continue ...
phpunit + xdebug
Для генерации отчетов, по покрытию кода тестами и др. статистической информации. Нам потребуется еще собрать xdebug. Если вдруг Ваша система содержит в портах, можете выполнить
# apt-get install php5-xdebug
Но если, нет ниже полный синтаксис
# cd /tmp
# svn co svn://svn.xdebug.org/svn/xdebug/xdebug/trunk xdebug
# cd xdebug
# phpize
# ./configure --enable-xdebug
# make
# make install
# php -i | grep xdebug | grep support
xdebug support => enabled
Выведена заветная строка, что означает что все установлено, правильно.
phpunit + selenium remote control
Не знаю понадобится Вам это или нет :). Но вдруг Вы захотите еще и прочитать продолжение этой статьи, в общем придется поставить :)
Ставим selenium-rc (больше информации на официальном сайте http://seleniumhq.org/). Да вы должны ставить selenium-rc только на сервера где есть графический интерфейс Windows/Linux with X server/MacOS
# cd /opt/
# wget http://selenium.googlecode.com/files/selenium-remote-control-1.0.3.zip
# unzip selenium-remote-control-1.0.3.zip
# mv selenium-server-1.0.3 selenium-server
# cd selenium-server
# java -jar selenium-server.jar >access.log 2>error.log &
После запуска сервера, пробуем к нему подключится :) Стандартный порт Selenium-RC - 4444.
#telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Коннект есть, все ок.
Для Linux with X (Ubuntu/Kubuntu/Xbuntu etc.). Запускаем selenium-rc сервер из консоли через ssh. Правда в таком случае вы сможете запускать тесты в FireFox на линуксе.
# export DISPLAY=:0
# java -jar selenium-server.jar >access.log 2>error.log &
php documentor
Собираем документацию с проекта. Сам проект хостится тут http://www.phpdoc.org/. Как всегда Вы можете поставить php-doc из apt.sources
# sudo apt-get install phpdoc
или через pear
# pear install PhpDocumentor
php code sniffer
Для проверки соответствия кода, стандартам принятым в компании. (Предполагается, что Вы все же используете Zend стандарты :) кодирования ). Сам проект http://pear.php.net/package/PHP_CodeSniffer/. Ставим из сорцов системы.
# apt-get install php-codesniffer
Или через любимый pear
# pear install PHP_CodeSniffer
# phpcs --version
PHP_CodeSniffer version 2.2.0 (stable) by Squiz Pty Ltd. (http://www.squiz.net)
Главное проверить, что корректно запускается, после установки.
php code browser
Вот теперь мы подошли к последнему компоненту. Сам проект хостится тут http://github.com/mayflowergmbh/PHP_CodeBrowser. Цель проекта, красиво раскрасить исходники, и также отметить те места где есть ошибки кодирования, провалились тесты, и т.д.
Установка, тут придется руками
# cd /opt/
# git clone git://github.com/mayflowergmbh/PHP_CodeBrowser.git
# mv PHP_CodeBrowser phpCodeBrowser
# /opt/phpCodeBrowser/bin/phpcb --help
Usage: phpcb --log <dir> --output <dir> [--source <dir>]
Собственно на этом все подготовительные работы по установке нужных библиотек и компонентов, можно считать завершенным. теперь попробуем взлететь :)
3. Конфигурация
Итак , для начала создадим папку проекта "testus"
# cd /opt/cruisecontrol/projects/
# mkdir testus
# cd testus
А теперь создадим папку с Build, где будет хранится вся информация по текущему билду (и если требуется исхоный код билда, но об этом позже)
# mkdir build
# mkdir build/api
# mkdir build/coverage
# mkdir build/logs
# mkdir build/php-code-browser
Создаем папку для исходников и чекаутим наш репозиторий
# cd mkdir source
# svn co http://secure.our-repository.com/svn/trunk source
Build.xml
СС, как приложение на Java, для запуска инструкций использует ANT (Подробнее о проекте http://ant.apache.org/). Файл располагаем в корне проекта /opt/cruisecontrol/projects/testus
Build.xml состоит из целей (target), и собственно параметров целей.
Опции build.xml
- "сheckout" - checkout исходники из репозитория
- "php-documentor" - создание документации для исходников (sources)
- "php-codesniffer" - проверка кода на соответствие стандартам кодирования ZendFramework (Документация http://framework.zend.com/manual/en/coding-standard.html)
- "php-code-browser" - генерация html файлов для броузинга по файлам через CC
- "phpunit" - запускаем юнит тесты, аппликейшн тесты и функциональные из папки source/tests
- "build" - цель по умолчанию, приводит к запуску всех вышеперечисленных целей в нужном порядке
Ниже приведен build.xml с комментариями.
failonerror="true" - опция сообщает СС завершать ли билд с сообщением, что сборка проекта не удалась. Конкретно для php можно использовать exit(code) , где code любое число отличное от нуля.
Для тестирования запустим тесты и проверим что все выполняется корректно:
# ../../apache-ant-1.7.0/bin/ant phpunit
А теперь запуcтим все цели вместе:
# ../../apache-ant-1.7.0/bin/ant
Config.xml
Сам файл располагаем в корне СС, тоесть в /opt/cruisecontrol. Config.xml состоит из секций <project> , в которых собственно описывается как обрабатывать данные результатов билда.</project>
Описание секции с комментариями ниже:
Каждая секция должна иметь уникальное имя <project name="NAME_OF_PROJECT"></project> buildafterfailed="false" - опция указывает, продолжать ли дальнейшую сборку проекта, при падении одной из целей. Желательно указывать false.
Проверять изменения в репозитории /repos/${project.name} каждые 30 секунд. При изменении, в очередь добавляется задание на сборку билда.
<modificationset quietperiod="30">
<svn RepositoryLocation="/repos/${project.name}"/>
</modificationset>
Собирать билд каждые 5 минут, принудительно
<schedule interval="300">
<ant anthome="/opt/cruisecontrol/apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
</schedule>
Инструкции для листера для текущего статуса билда
<listeners>
<currentbuildstatuslistener file="/opt/cruisecontrol/logs/${project.name}/status.txt"/>
</listeners>
Папки откуда взять логи билда
<log dir="/opt/cruisecontrol/logs/${project.name}">
<merge dir="/opt/cruisecontrol/projects/${project.name}/build/logs/"/>
</log>
Секция <publishers>...</publishers> будет выполнена после того билд собран успешно или не успешно. Это используется для сбора статистической информации, построения графиков, а также для отправки уведомлений. Для отправки доступны email/messengers etc.
Команда для генерации графиков метрик
<execute command="/opt/phpUnderControl/bin/phpuc.php graph logs/${project.name} artifacts/${project.name}" />
Main.jsp
Итак осталось дело за малым. Открываем /opt/cruisecontol/webapps/cruisecontrol/main.jsp. Только предварительно сделайте копию оригинального.
И собственно убираем лишние if. Так чтоб содержимое секции <cruisecontrol:tabsheet> было следующим
<cruisecontrol:tabsheet>
<tr>
<td>
<%-- phpUnderControl 1 --%>
<cruisecontrol:tab name="buildResults" label="Overview" >
<%@ include file="buildresults.jsp" %>
</cruisecontrol:tab>
<%-- phpUnderControl 2 --%>
<cruisecontrol:tab name="testResults" label="Tests" >
<%@ include file="phpunit.jsp" %>
</cruisecontrol:tab>
<%-- phpUnderControl 3 --%>
<cruisecontrol:tab name="metrics" label="Metrics" >
<%@ include file="metrics.jsp" %>
</cruisecontrol:tab>
<%-- phpUnderControl 4 --%>
<% if (coverage) { %>
<cruisecontrol:tab name="coverage" label="Coverage">
<cruisecontrol:artifactsLink>
<iframe src="<%=request.getContextPath() %>/<%= artifacts_url %>/coverage/index.html" class="tab-content">
</iframe>
</cruisecontrol:artifactsLink>
</cruisecontrol:tab>
<% } %>
<%-- phpUnderControl 5 --%>
<% if (browser) { %>
<cruisecontrol:tab name="codeBrowser" label="Code Browser">
<cruisecontrol:artifactsLink>
<iframe src="<%=request.getContextPath() %>/<%= artifacts_url %>/php-code-browser/index.html" class="tab-content">
</iframe>
</cruisecontrol:artifactsLink>
</cruisecontrol:tab>
<% } %>
<%-- phpUnderControl 6 --%>
<% if (apidoc) { %>
<cruisecontrol:tab name="documentation" label="Documentation">
<cruisecontrol:artifactsLink>
<iframe src="<%=request.getContextPath() %>/<%= artifacts_url %>/api/index.html" class="tab-content">
</iframe>
</cruisecontrol:artifactsLink>
</cruisecontrol:tab>
<% } %>
<%-- phpUnderControl 7 --%>
<cruisecontrol:tab name="phpcs" label="CodeSniffer">
<%@ include file="phpcs.jsp" %>
</cruisecontrol:tab>
<%-- phpUnderControl 8 --%>
<cruisecontrol:tab name="pmd" label="PHPUnit PMD">
<%@ include file="phpunit-pmd.jsp" %>
</cruisecontrol:tab>
<%-- phpUnderControl 9 --%>
</td>
</tr>
</cruisecontrol:tabsheet>
На этом настройка закончена и можно переходить к запуску :)
4. Запуск
Для того чтобы запустить СС, достаточно выполнить в папке /opt/cruisecontrol
# ./cruisecontrol.sh
[cc]May-23 11:45:00 Main - CruiseControl Version 2.8.3 Compiled on January 24 2010 2134
И после окончания Вы можете открыть свой браузер с http://your.server.ip80 и наблюдать список модулей. Перейдем по стандартному урлу для СС. http://your.server.ip80/cruisecontrol/ и результат будет похож на скиншоты из секции 5.
5. Результат
Если все собрано правильно Вы должны увидеть следующее :)
И на странице метрик следующее :)
Надеюсь, что данная статья поможем Вам внедрить CI (Continuous Integration) для своих проектов и повысить качество и стабильность Ваших приложений. От себя все Cheers, если что пишите по известному адресу: necromant2005 ### gmail.com. Ссылки на используемые библиотеки и проекты , ниже.
6. Ссылки
Расширение phpUnderControl: http://www.phpundercontrol.org
ezComponents: http://ezcomponents.org
phpUnit: http://www.phpunit.de/
xdebug: http://xdebug.org/
Selenium: http://seleniumhq.org/
php-documentor: http://www.phpdoc.org/
php-code-sniffer: http://pear.php.net/package/PHP_CodeSniffer/
php-code-browser: http://github.com/mayflowergmbh/PHP_CodeBrowser
Уважаемые читатели, высказывайте, пожалуйста ваше мнение о статье в комментариях или в теме на форуме, хотели бы вы прочесть продолжение?
- Спрашивать почему у вас не работает код, для этого есть тема форума закрепленная за статьей.
- Спрашивать как реализовать ту или иную функциональность, для этого необходимо создать свою тему на форуме.
Комментарии для того чтобы: высказать свое аргументированное мнение о статье, указать какие участки вызывают непонимание, что нужно исправить/улучшить, просто сказать спасибо.
Комментарии имеют древовидную структуру.
Если вы хотите ответить на определенный комментарий - нажмите на ссылку "Ответить" возле этого комментария.