Pull to refresh

Система непрерывной интеграции своими руками

Reading time4 min
Views8.1K
Доброго времени суток, %username%!

О непрерывной интеграции можно почитать здесь и вообще поискать литературу на данную тематику, если станет интересно. Если Вы уже осознали всю выгоду использования CI, то продолжу развивать мысль. Наиболее популярные из существующих систем непрерывной интеграции: Hudson, TeamCity и CruiseControl. Во всех этих системах настройка билда обычно осуществляется через UI. Выбираем что надо сделать в окошке браузера — и билд автоматизирован (естественно можно написать свои скрипты и запускать их). Обилие настроек и всяческих примочек. И я подумал, а что сделали создатели этих систем? А сделали они просто команды для различных билдеров, компиляторов, тестирующих и прочих инструментов, чтобы разработчик не тратил своё время на эти вещи. А так ли много времени уйдет на написание своей системы и команд?

Для небольших проектов я использую всего несколько инструментов:
  • .NET платформа для разработки
  • MS SQL Server для баз данных
  • NUnit для тестирования
  • … может еще пара каких-нибудь инструментов

так почему бы самому не изучить опции командной строки необходимых мне инструментов, написать пару скриптов и автоматизировать весь процесс. Я не говорю, что это лучшее решение, просто мне захотелось изобрести этот замечательный велосипед, который называется CI.
При разработке более-менее серьезных приложений в приличных компаниях используют систему контроля версий. И в большинстве из них есть такие хуки (hooks) — обработчики событий репозитория. Именно этот способ автоматизации первым пришел мне в голову.

В качестве VCS будем использовать svn (на самом деле в других системах различия в хуках минимальны, либо их вообще нет).

1. Создадим репозиторий.
2. Идем в папку hooks и создаем там post-commit.bat. В этот батник мы запишем команду, которая должна выполняться после каждого коммита.
3. Делаем чекаут из репозитория. Создадим папку CI, чтобы не захламлять корневую директорию. В папке CI создаем файл Run.bat, в котором и будет описан весь наш процесс.
4. В post-commit.bat запускаем Run.bat — вот и вся автоматизация

post-commit.bat:
D:\Work\SomeProject\CI\Run.bat

Разрабатываемый проект — библиотека классов на .NET с некоторым набором тестов.

Итак, определим функции для нашей системы CI


  1. Получение исходного кода из репозитория
  2. Быстрый билд после коммита и запуск юнит тестов после билда
  3. Уведомление о результате билда


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

1. Получение исходного кода из репозитория


Для этого достаточно выполнить команду svn update. При каждом изменении обновление будет занимать минимум времени (как вариант можно очищать полностью папку и делать checkout)

2. Быстрый билд после коммита и запуск юнит тестов после билда


Для этих целей воспользуемся скриптом msbuild:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Test" xmlns="schemas.microsoft.com/developer/msbuild/2003">
     <!-- Import the MSBuild Tasks -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<ClassLibraryOutputDirectory>bin\$(Configuration)</ClassLibraryOutputDirectory>
<ProjectDir>SomeSolution\SomeProject</ProjectDir >
<ProjectTestDir>SomeSolution\SomeTests</ProjectTestDir >
<ProjectFile>$(ProjectDir)\SomeProject.csproj</ProjectFile >
<TestProjectFile>$(ProjectTestDir)\SomeTests.csproj</TestProjectFile >
</PropertyGroup>
 
<!-- Build projects by calling the Project files generated by VS -->
<Target Name="Build">
<MSBuild Projects="$(ProjectFile)" />
<MSBuild Projects="$(TestProjectFile)" />
</Target>
 
<!-- Run Unit tests -->
<Target Name="Test" DependsOnTargets="Build">
<Exec Command=""%PROGRAMFILES%\NUnit 2.5.10\bin\net-2.0\nunit-console.exe" $(ProjectTestDir)\$(ClassLibraryOutputDirectory)\SomeTests.dll /xmlConsole" />
</Target>
</Project>

Результаты выполнения MSBuild положим в папку CI\Logs перенаправлением стандартного потока вывода в файл

3. Уведомление о результате билда


В большинстве систем CI реализована возможность отправки писем с уведомлениями, но для таких скромных целей отсылать письмо и захламлять свой ящик я не захотел, поэтому решил ограничиться отсылкой сообщения в ICQ. С использованием библиотеки NOscar написал небольшое консольное приложение которое гибко конфигурируется и отсылает сообщение списку uin-ов. Сообщение будем формировать на основе поиска в ранее полученном логе билда строки «Build succeeded.»

Все шаги вроде проработаны, осталось выполнить их последовательно.


CI\Run.bat:
cd /d …
REM 1. Get Last sources
svn update
REM 2. Build and Run Unit Tests
"%windir%\Microsoft.NET\Framework\v3.5\msbuild.exe" Master.build > CI\Logs\build.log
REM 3. Send notification
set "Message=Build succeeded."
find "Build succeeded." CI\Logs\build.log > NUL
if %errorlevel% equ 1 set "Message=Build failed."
CI\Notifier\ICQSender.exe "%Message%"


В результате получилась достаточно легковесная автоматизированная CI система, которую можно легко и с пользой для себя расширять, изучая подробнее инструменты, с которыми работаете. И, что немаловажно, процесс становится более наглядным, из-за чистоты директорий (отсутствует пачка универсальных скриптов, которые мы не используем).

Спасибо за внимание

P.S.: Есть идея написать этакую фабрику по генерации таких скриптов. Захотел скрипт — зашел на сайт — пару последовательных страниц с полезными советами и подсказками — получаешь на скачивание файлик скрипта — кинул в папку — готово. Конечно, с мощностями современных серверов легче поставить один из существующих, но все же приятнее, когда нет лишнего в папках, более ясная картина что происходит, ничто не путает.
Tags:
Hubs:
Total votes 8: ↑6 and ↓2+4
Comments1

Articles