Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.
Это определение находится в статье Мартина Фаулера.
Таким образом данный подход предполагает частые интеграции, желательно после каждого комита кода в репозиторий. Необходимо сбилдить проект, запустить тесты и разместить текущую версию на тестовый сервер. Это надо делать постоянно, значит надо автоматизировать.
Мой первый опыт автоматизации процесса билда проекта был с использованием MsBuild. Я написал скрипт, выполняющий нужные мне действия в нужной последовательности. Файлик находился под управлением контроля версий и все было хорошо. До тех пор, пока не понадобилось обновить собственно сам скрипт. MsBuild загружает файл один раз и потом выполняет все действия указанные в нем, значит обновленную версию скрипта можно получить только после запуска устаревшего. Как результат, для получение последней версии продукта необходимо дважды выполнять процесс билда (пжервый раз со старым скриптом, который заставит обновить исходный код, второй с новой версией, который выполнит необходимые действия). Это одна из причин почему я считаю что один билд скрипт не достаточно удобен.
В этом посте будет рассмотрено как быстро настроить CI (Continuous Integration) сервер используя Cruise control .net.
По теме настройки сервера так же можно почитать следующие два туториала:
Итак начнем.
- Установка
- Добавляем проект
- Настройка системы контроля версий
- Билд
- Тестирование
- Уведомления
Установка
Скачать CC.NET можно тут. Для этого поста используется последняя на данный момент стабильная версия, а именно 1.5.
Во время установки CC.NET создаст виртуальный каталог в IIS, по умолчанию имя этого каталога ccnet. Таким образом попасть на страницу билд сервера можно будет попасть по адресу http://localhost/ccnet.
В папке, куда будет уставлен CC.NET будет создано 3 папки Examples, server и webdashboard.
В папке server нас будет интересовать файл ccnet.config – это обычный xml файл, в котором хранятся настройки для проектов. Т.е. в нем описывается последовательность действий (таких как получить изменения из репозитория кода, сбилдить проект, запустить тесты и т.д.). Документацию по настройкам в этом файле можно найти тут.
В папке webdashboard находятся настройки веб части CC.NET. В ней можно увидеть результаты билдов, логи, отчеты и т.д.
Добавляем проект
Чтобы добавить проект добавляем в файл ccnet.config тег project, чтобы получилось примерно следующее:
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project>
<name>Имя проекта</name>
<workingDirectory>Рабочая директория</workingDirectory>
<artifactDirectory>Артефакты</artifactDirectory>
<webURL>Url для веб</webURL>
<project>
<tasks>
Задания
</tasks>
<publishers>
Сообщение о результатах
</publishers>
</cruisecontrol>
- имя проекта будет отображаться на сайте, в отчетах и т.д.
- рабочая директория – место где будут храниться временные файлы
- артефакты – сюда попадают результирующие файлы логов и отчеты
- Url для веб – этот адрес используется в письме cc.net, которое отсылается после билда.
- задания – раздел где указывается какую последовательность действий требуется выполнить в процессе билда
- сообщение о результатах – как оповещать команду о результате билда. Одной из ошибок бывает расположение рассылки о результатах в блоке tasks. Но при провале одной из последовательных задач оставшаяся очередь не выполняется, и значит никто не получит уведомления. Блок publishers не может стать причиной неудачного билда, только tasks
Настройка системы контроля версий
В качестве примера будет рассмотрена subversion, но CC.NET поддерживает и другие. В документации очень четко написано, какие необходимы настройки. CC.NET достаточно умен чтобы автоматически обновлять исходный код, и если код еще не был получен автоматически забирать весь код из репозитория
Сам раздел описывать не вижу смысла, он слишком очевиден и очень подробно описан, но есть одна особенность работы с svn – CC.NET использует команды для работы с svn вида “svn commit”. После чего говорит что не находит нужную программу для выполнения. Это происходит потому, что устанавливая turtoise svn он не содержит файла svn.exe, наличие которого предполагает CC.NET. Заставить работать удалось только при помощи установки visual svn, в котом есть файл svn.exe.
Билд
Для автоматизации билда можно использовать либо MsBuild, либо NAnt. У меня есть опыт использования обоих.
Скрипты MsBuild для меня показались очень большими и неудобными. Он генерируются вижуал студией в файлах csproj. И все хорошо пока не приходится писать эти вещи вручную. Далее становится все неудобно и слишком длинные названия начинают напрягать и раздражать. Но это лично мои впечатления. Еще одна проблема в том, что MsBuild никак не сможет сбилдить Setup project.
Теперь про NAnt. Честности ради стоит заметить что и NAnt не умеет билдить Setup project’ы, но его можно настроить использовать вижуал студию в качестве средства билда. Xml файлы для NAnt очень похожи на MsBuild и соответственно знание последнего обеспечит легкий переход, но в то же время они меньше, теги называются адекватней (опять же исключительно мое субъективное мнение).
Итак создадим первое задание – компиляция проекта. Для работы с NAnt (так же как и с MsBuild) СС.NET содержит специальный таск. Изменяем ccnet.config чтобы получилось следующее:
<tasks>
<nant>
<executable>C:\nant\nant-0.86-beta1\bin\nant.exe</executable>
<baseDirectory>C:\builds</baseDirectory>
<buildFile>default.build.xml</buildFile>
</nant>
</tasks>
Указываем путь к nant, указываем директорию в которой лежит скрипт, указываем название самого скрипта. Содержимое default.build.xml может быть следующим:
<project default="default">
<property name="devEnvPath" value="C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.com" />
<target name="compileDebug">
<exec program="${devEnvPath}">
<arg value="Путь к .sln файлу" />
<arg value="/build"/>
<arg value="Debug" />
</exec>
</target>
<target name="default" depends="compileDebug" />
</project>
Не знаю что тут можно прокомментировать, вроде все очевидно.
Тестирование
Запуск тестов
Для тестов с использованием NUnit CC.NET содержит готовый таск. Самый простой вариант:
<nunit>
<path>C:\Program Files\NUnit 2.5.2\bin\net-2.0\nunit-console.exe</path>
<assemblies>
<assembly>Путь к сборке с тестами</assembly>
</assemblies>
</nunit>
Если хотя бы один тест провалится, весь таск будет считаться не выполненным. На этом закончится выполнение тасков, и CC.NET начнет выполнение паблишеров, которые должны сообщить о результате билда.
Проверка покрытия
Еще одной очень полезной вещью может быть задание на проверку покрытия кода тестами. Для того, чтобы получить эту информацию можно воспользоваться утилитой NCover. Она строит очень подробные и информативные репорты. Для интеграции в CC.NET можно использовать задание NCover Profiler. Этот таск запустит тесты и сохранит отчет о покрытии тестами. Например таск может быть таким:
<ncoverProfile>
<executable>C:\Program Files\NCover\NCover.Console.exe</executable>
<program>C:\Program Files\NUnit 2.5.2\bin\net-2.0\nunit-console.exe</program>
<testProject>Путь к dll с тестами</testProject>
<includedAssemblies>*.dll</includedAssemblies>
</ncoverProfile>
Это задание проверит покрытие всех dll вашего проекта.
Так же есть полезный таск NCover Reporting. C помощью него на основании результатов полученных после NCover Profiler можно генерировать html отчеты.
<ncoverReport>
<executable>C:\Program Files\NCover\NCover.Reporting.exe</executable>
<outputDir>Reports</outputDir>
</ncoverReport>
Чтобы увидеть результаты работы этого таска в веб интерфейсе необходимо отредактировать файл dashboard.config (находится в папке webdashboard). В разделе buildPlugins необходимо добавить следующее:
<htmlReportPlugin description="Full NCover Report" actionName="FullNCoverBuildReport" htmlFileName="NCover\fullcoveragereport.html" />
После этого в отчете по билду слева появится новая ссылка:
Уведомления
За уведомления отвечает раздел конфигурации publishers. CC.NET содержит множество готовых способов уведомления (email, rss, cc.net tray и т.д.). Я использую email, конфигурация довольно проста:
<email from="адрес с которого посылать письмо" mailhost="smtp сервер" mailport="25" includeDetails="true" useSSL="false" mailhostUsername="имя пользователя" mailhostPassword="пароль">
<users>
<user name="имя пользователя" group="группа" address="адрес"/>
</users>
<groups>
<group name="buildmaster" >
<notifications>
<notificationType>Always</notificationType>
</notifications>
</group>
</groups>
<xslFiles>
<file>xsl\header.xsl</file>
<file>xsl\compile.xsl</file>
<file>xsl\unittests.xsl</file>
<file>xsl\modifications.xsl</file>
</xslFiles>
</email>
Результаты каждого билда будут высылаться согласно этой части конфигурационного файла.