framework.zend.com
Stable релиз 2.0 / 1.12

CruiseControl (CC) и Continuous Integration (CI)

К комментариям

  1. Введение
  2. Установка
  3. Конфигурация
  4. Запуск
  5. Результат
  6. Ссылки

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
  • Создание отчетов по сборке, что собралось, что не собралось, почему и т.д.
  • Создание статистических отчетов
    1. Удачных билдов vs заваленных
    2. Покрытия кода тестами, документаций etc.
    3. Количество методов, строк, файлов, классов etc.
    4. Время затраченное на сборку
  • Создание документации по проекту/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

  1. "сheckout" - checkout исходники из репозитория
  2. "php-documentor" - создание документации для исходников (sources)
  3. "php-codesniffer" - проверка кода на соответствие стандартам кодирования ZendFramework  (Документация http://framework.zend.com/manual/en/coding-standard.html)
  4. "php-code-browser" - генерация html файлов для броузинга по файлам через CC
  5. "phpunit" - запускаем юнит тесты, аппликейшн тесты и функциональные из папки source/tests
  6. "build" - цель по умолчанию, приводит к запуску всех вышеперечисленных целей в нужном порядке

Ниже приведен build.xml с комментариями.

См. приложение 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>

См. приложение config.xml

Описание секции с комментариями ниже:
Каждая секция должна иметь уникальное имя <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. Результат

Если все собрано правильно Вы должны увидеть следующее :)

cruisecontrol phpundercontrol continues integration

И на странице метрик следующее :)

cruisecontrol phpundercontrol continues integration metrics

Надеюсь, что данная статья поможем Вам внедрить CI (Continuous Integration) для своих проектов и повысить качество и стабильность Ваших приложений. От себя все Cheers, если что пишите по известному адресу: necromant2005 ### gmail.com. Ссылки на используемые библиотеки и проекты , ниже.

6. Ссылки

Основной сайт проекта: http://cruisecontrol.sourceforge.net
Расширение 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

Уважаемые читатели, высказывайте, пожалуйста ваше мнение о статье в комментариях или в теме на форуме, хотели бы вы прочесть продолжение?

Тема на форуме

Лучший способ следить за обновлениями сайта это подписаться на RSS
Если информация была полезной для вас, вы можете поддержать сайт.
Комментарии:
Станислав Малкин 28.05.2010 13:35 #
Почему ant, а не phing?
Ответить
IgorN 28.05.2010 14:16 #
Тема очень интересная и объемная. Со сборкой столкнулся в Ruby on Rails, но тогда не представлял, что это такое и с чем его едят.
Как по мне использовать надо.
И действительно почему не phing? Как я понял ANT на Java, тогда отдаю предпочтение phing который написан на пхп и легко расширяем.
Подобные инструменты заставят людей писать тесты, я вот себя не могу пока заставить, так как в зф, нет для этого нормальных инструментов, в RoR писал, но там все просто и лишних телодвижений по установке доп. либ и настройке делать не надо.
Ответить
IgorN 28.05.2010 14:17 #
Статья супер! Автору респект! Но не все под линуксом сидят... с этим надо что то делать :)
Ответить
patt 26.11.2010 15:11 #
Тем, кто не сидит, нужно пересаживаться:) всё таки хостятся пхп сайты в 99.9% на юникс подобнх ос... и разрабатывать желательно на такой же системе.
Ответить
lcf 28.05.2010 15:42 #
Сложилось впечатление некоторой непоследовательности и ужатости материала, но это самую малость.

Как инструкция по установке доступна изложенная включающая минимально необходимые нюансы - супер. Не уверен что подразумевается в продолжении, но заранее говорю что с удовольствием бы прочитал. Возможно какие-то тонкости процесса использования тех или иных модулей, если они есть, или более детализированное описание итерации. Вообщем - пиши ещё :)
Ответить
Сергей 28.05.2010 17:44 #
Спасибо большое за статью.
Ответить
Necromant2005 28.05.2010 18:12 #
На самом деле цель статьи что начать с чего-то стартануть, и настроить начальное окружение. Вообще использование CI и CruiseControl схоже на фонарь, который подсвечивает все что конкретно делатеся у тебя в проекте, показывая покрытие тестами, процент broken builds, соблюдение код стандартов, документацию и т.д. Особенно удобно при разработке большими командами, или распределенными командами, когда разные части проекта паралельно модифицирую разные люди с разными целями, но с другой стороны должно проподлжать коретно работать. Также удобно мониторить вообще что происходит с проектом и держать руку на пульсе разработки.

@Станислав @IgorN ant - потому, что это стандрный инструмент для организации сборки входящий в состав самого СruiseСontrol.

@IgorN Zend уже сейчас содержит все необходимое для того чтоб писать тесты с нуля. Также документация по ZF предлагет примеры написания тестов их огранизацию и запуск.
Ответить
lcf 28.05.2010 18:26 #
Вот, первый абзац комментария добавить во введение :)
Ответить
makedon 29.05.2010 16:35 #
Спасибо за статью, тема очень интересная, надеюсь будет продолжение.

Подобные инструменты делают разработку более комфортной и более дисциплинированной и гарантируют качество продукта.

Отлаженный рабочий процесс не отвлекает разработчика от написания кода, а пройденные тесты повышают удовольствие от работы в целом.



Все выглядит очень привлекательно, но очень интересно узнать где тут подводные камни и насколько такой подход продуктивен?
Ответить
Станислав Малкин 01.06.2010 04:33 #
про это уже где-то читал статью. Наверное на хабре.1
Ответить
makedon 06.06.2010 03:55 #
Как я писал выглядит очень привлекательно и идеально.

Но думаю тут есть недостатки:
1) разработчик должен быть достаточно квалифицирован и стрессоустойчив - думаю что система не позволит закоммитить код не прошедший тесты или не соответствующий Zend стандартам.

2) новый разработчик должен будет привыкнуть к такому инструментарию и особенностям работы (в Google например первых несколько недель учат пользоваться инструментарием и рабочим процессом - думаю там СС и СI или подобное).

3) тесты и соответствие стандартам улучшают качество кода, но как мне кажется снижают скорость разработки. Это важно например в моменты deadline.


Более кратко звучит так: мы повышаем качество кода за счет более длительных сроков разработки.
Ответить
duburlan 16.03.2012 11:50 #
90% времени разработчик проводит читая код. Только 10% времени он его пишет.
TDD не увеличивает время разработки а наоборот уменьшает, и как не парадоксально удешевляет.
Если проект долгоживущий, то всегда быстрее и дешевле писать качественный покрытый тестами код.
А дедлайны это косяк либо планирования либо неадекватности начальства, и это не оправдания для кривокода.
Ответить
Zh0rzh 18.06.2010 11:10 #
Хорошая статья как пособие по установке!

Ростислав, хотелось бы услышать твое мнение в более абстрактном виде.

Как используешь?
Какая польза?

О самом CI и перечисленных возможностях (selenium, phpcs, phpunit, ...)
Ответить
Владимир 15.05.2011 09:29 #
Если в листинге перед строкой стоит "#", то это значит, что команда исполняется от пользователя root. Следовательно, sudo вводить не надо. Проверьте статью пожалуйста.
Спасибо.
Ответить
wmix 22.08.2011 03:16 #
Огромное большое спасибо за статью. пусть написанно немного суховато, и при установке пришлось покопаться в интернте, но после успешной установки, откинулся на стульчике, наслождаясь контролем над круизом.

от себя хотелось бы добавить, что изменение main.jsp совершенно ненужно, все было продуманно, и встаки iframe-ов решаются на уровне config.xml Секция publishers тагом artifactspublisher

[artifactspublisher dir="projects/${project.name}/build/coverage" dest="artifacts/${project.name}" subdirectory="coverage"/]
Ответить
Уважаемые пользователи. Комментарии не для того чтобы:
  1. Спрашивать почему у вас не работает код, для этого есть тема форума закрепленная за статьей.
  2. Спрашивать как реализовать ту или иную функциональность, для этого необходимо создать свою тему на форуме.

Комментарии для того чтобы: высказать свое аргументированное мнение о статье, указать какие участки вызывают непонимание, что нужно исправить/улучшить, просто сказать спасибо.

Комментарии имеют древовидную структуру.
Если вы хотите ответить на определенный комментарий - нажмите на ссылку "Ответить" возле этого комментария.

Комментарии не соответствующие этим правилам могут быть удалены. Спасибо за понимание.
Комментарии временно отключены, вы можете воспользоваться форумом.