Управление сборкой проектов вместе с teamcity. Часть 2

July 27, 2009Comments Off on Управление сборкой проектов вместе с teamcity. Часть 2

Я продолжаю рассказ о teamcity и о том, как с его помощью мы можем вынести процесс управления разработкой программного обеспечения на новый уровень. Технически, teamcity относится к классу продуктов build management and continuous integration. Такие инструменты используются отделом управления качеством и предназначены для того, чтобы извлечь из cvs/svn-репозитория последнюю версию исходников проекта и собрать проект (билд). Затем билд будет подвергнут набору автоматических и ручных тестов.

Кратко напомню, что в прошлой статье я рассказал о назначении teamcity, о составляющих его частях и политике лицензирования. Для того, чтобы показать методы интеграции teamcity с системой управления версиями документов я рассказал об установке и настройке SVN-сервера VisualSVN. Для демонстрации возможностей teamcity нам потребовался проект, и я решил использовать для этой цели небольшой java-проект, управляемый с помощью maven. Последним шагом подготовки было импортирование файла проекта и всех составляющих проект ресурсов внутрь SVN-репозитория. Все дальнейшие действия теперь связаны только с работой внутри веб-панели управления teamcity. Прошлая статья завершилась на том, что я рассказал только об одном разделе настроек teamcity – настройке билд-агентов. Теперь мы полностью готовы к тому, чтобы создать внутри teamcity проект и назначить для него билд-конфигурацию. Так что поехали.

Для создания нового teamcity-проекта вам необходимо зайти в панель управления teamcity от имени администратора и затем перейти на закладку “Administration”. Там вы увидите список всех созданных проектов и привязанные к ним билд-конфигурации. Для создания нового проекта используйте функцию “Create project”. Ничего сложного на появившемся диалоговом окне создания нового проекта нет: просто укажите имя проекта и произвольный комментарий описания. Фактически, проект – это способ группировки нескольких билд-конфигураций в единую административную единицу. Например, разрабатывая проект (назовем его “MultiProject”) для нескольких платформ, например, windows и linux, вы создадите две билд-конфигурации с различными настройками, и выполняющиеся под различными билд-агентами. Т.е. билд-агент на windows машине выполняет сборку проекта для windows, а билд-агент на lunux-машине выполняет, соответственно, сборку того же проекта, но для linux-окружения. Итак, создав проект, давайте присоединим к нему билд-конфигурацию. Для этого я использую кнопку “Create build configuration”. Для настройки билд-конфигурации необходимо пройти через ряд последовательных шагов мастера создания билд-конфигурации. Первый экран мастера настройки называется “General Settings” (см. рис. 1).



Единственные очевидные параметры из указываемых на этом экране это “Name” и “Description”, т.е. название билд-конфигурации и комментарий к ней. Параметры “Build number format” и “Build counter” должны рассматриваться совместно: первый из них – это шаблон, согласно которому будут нумероваться билды и, в самом простом случае, номер билда – это просто число. Комбинация символов “{0}” означает, что вместо них teamcity подставит в номер билда число, увеличивающееся при каждом очередном билде на единицу. Текущее значение этого числа как раз и хранится в поле “Build counter”. Графа “Artifact paths” требует более детального рассмотрения и примера, а пока можно сказать, что каждая сборка по своему завершению может генерировать несколько выходных файлов (в терминологии teamcity артефактов). Самый очевидный пример артефакта – это сам финальный файл билда, т.е. наше приложение, которое затем поступит для тестирования. Другими примерами артефактов могут быть отчеты о ходе компиляции, отчеты о результатах автоматического тестирования встроенного в билд-цикл. Фактически, любой файл или каталог, формируемый в ходе билда, может стать артефактом. После того как билд будет завершен и всем заинтересованным участникам будет разослано сообщение об этом, то пользователь, зашедший на страничку с уведомлением о результатах билда, увидит также перечень ссылок позволяющих скачать созданные артефакты. Следующая графа “Fail build if” служит для того, чтобы задать перечень критериев, позволяющих определить то, что билд был провален. Традиционно, все билд-утилиты извещают о результате своего завершения через код возврата “build process exit code is not zero” . Также можно пометить билд как “проваленный”, если был провален хотя бы один из автоматических тестов “at least one test failed”, или если билд выполняется слишком долго (завис) “it runs longer than X minutes”. Из оставшихся на странице “General Settings” опций единственная представляющая интерес – “enable hanging builds detection” - т.е. включить режим обнаружения “зависших билдов”.

Завершив со страницей “General Settings” переходим к следующей странице “Version Control Settings”. Эта страница служит для управления правилами интеграции teamcity и системы управления версиями документов. Первым шагом нужно настроить VCS Root, т.е. зарегистрировать cvs/svn репозиторий, указав для него путь и учетную запись для подключения. С целью этого жмем на кнопку “Create and attach new VCS root” и попадаем на страницу “New VCS Root”. Здесь нужно указать название VCS Root и выбрать из падающего списка тип используемой вами системы хранения версий документов. После того как я выбрал “Subversion” то на экране появится ряд опций настройки подключения к svn-репозиторию. В графе “URL” я указываю значение http://localhost:8080/svn/demo1/ (см. прошлую статью, где я рассказывал о настройке VisualSVN). Обратите внимание, что я указал не полный путь к, непосредственно, каталогу с исходными кодами проекта (они расположены по адресу http://localhost:8080/svn/demo1/trunk/tcitydemo1/), а указал путь к корню репозитория, выделенного для хранения проекта. Дело в том, что в терминологии teamcity “VCS Root” не является непосредственным адресом, по которому расположен проект или его HEAD-версия. Скорее,VCS Root является “точкой доступа”, т.е. адрес сервера, учетные записи для доступа и сведения о структуре репозитория. Далее, в графах “User name” и “password” я указываю имя и пароль пользователя имеющего право работать с svn-репозиторием. Наверняка вам пригодятся настройки управляющие работой с внешними для svn-репозитория зависимостями “Externals support”. Напомню, что в практике проект может быть распределен по нескольким svn-репозиториям. К примеру, мы можем использовать конфигурацию 2 + 1, т.е. два репозитория хранят независимые друг от друга проекты, а третий репозиторий хранит единую для двух проектов часть, например, общие библиотеки. Если мы хотим, чтобы teamcity “вытягивал” из внешних репозиториев ресурсы, на которые есть ссылки “svn:externals” и затем визуально оформлял в виде статистики изменений по репозиторию не только локальные, но и “внешние” изменения, то укажите режим “Full support (load changes and checkout)”. Режим же “Checkout, but ignore changes” приведет только к извлечению “внешних” исходников проекта, но не включению их в статистику изменений. После того как я создал VCS Root, то возвращаюсь на страницу настройки VCS и должен указать еще несколько настроек. Во-первых, “checkout rules”, т.е. правила по которым из CVS Root будут извлечены каталоги с исходными кодами проекта. Для этого я использую кнопку “edit checkout rules” и попадаю в диалоговое окно с правилами “отображения” структуры svn-репозитория на каталоги build-агента.
+:trunk/tcitydemo1=>.
Указанное выше правило говорит, что нужно извлечь все файлы и подкаталоги, расположенные внутри “trunk/tcitydemo1” (перед префиксом добавляется адрес VCS Root) и поместить их в корень каталога копии проекта. Можно записать несколько правил импорта файлов из репозитория, можно комбинировать эти правила, например, исключая из импорта файлы по определенной маске и т.д. В любом случае, мы сказали teamcity как извлечь из репозитория файлы, и теперь пора задуматься о том, что произойдет далее с собранной структурой проекта. Следующая опция настройки VCS – “VCS checkout mode” – имеет следующие значения. Во-первых, “Automatically on Server” предполагает, что работа с svn-репозиторием будет выполнена на teamcity сервере, а затем файлы проекта будут скопированы на машины с билд-агентами. Как побочный эффект этой стратегии на машины с билд-агентами не будут скопированы служебные файлы svn (скрытый каталог “.svn”). Вторая возможная стратегия “Automatically on Agent” предполагает, что файлы из svn-репозитория будут загружены не сервером teamcity, а билд-агентом (в этом случае, служебный каталог “.svn” будет доступен). Третья стратегия “Do not checkout files automatically” предполагает, что файлы из репозитория должны быть доступны заранее до начала, собственно, процесса сборки проекта. Указав режим автоматического извлечения файлов сервером, я перехожу к остальным опциям. “Clean all files before build” служит для предварительной очистки каталогов с исходными кодами проекта, перед тем как эти файлы будут заново извлечены из svn-репозитория. Одна из самых полезных функций связанных с интеграцией с svn является возможность маркировать метками “удачные” билды. Т.е. предположив, что какой-то билд был удачен, мы можем сделать в svn-репозитории копию файлов образующих этот билд. В последствии мы всегда можем вернуться именно к этому состоянию репозитория и проекта. Или мы можем сравнить, то какие файлы были изменены между двумя произвольными метками. Билды, точнее образующие их файлы проекта, могут маркироваться либо автоматически, либо вручную. Для автоматического режима нужно включить опцию “VCS labeling mode”, установив ее в “Successful only”, а в графе “Labeling pattern” указывается правило назначения имени метки, например, “label_%system.build.number%”. Здесь вместо “%system.build.number%” будет подставляться номер билда.

Третий шаг настройки конфигурации билда – выбор “Build Runner”. Именно здесь мы указываем то какая утилита выполняет фактическую сборку проекта. Для нашего примера java проекта управляемого maven необходимо выбрать в падающем списке “Build Runner” вариант “maven 2”. Также есть поддержка ant-управляемых проектов, проектов для visual studio, ruby-проектов. Остальные настройки для “Build runner”-а специфичны именно для maven2. Во-первых, в графе “Goals:” указывается список целей, которые нужно выполнить maven-у. Здесь я указал значение “clean install”. Графа “Maven home path” позволяет указать путь к каталогу, где у вас на машине с билд-агентом установлен maven. Большой необходимости в том, чтобы заполнять это поле нет, т.к. в инсталляционном пакете teamcity уже идет интегрированный maven 2.0.9 (для teamcity 4.5.1). Остальные параметры, связанные с настройкой maven тривиальны. “Additional Maven command line parameters” позволяют указать дополнительные параметры командной строки для maven. Если мы хотим использовать нестандартный файл settings.xml, то путь к нему указывается в графе “User settings path”. В том случае, если мы хотим выполнять сборку проекта под версией java отличной от установленной по-умолчанию на машине с билд-агентом, то нужно указать путь к ней в графе “JDK home path”. Поле “JVM command line parameters” позволяет настроить специфические параметры java-машины используемой для запуска maven-сценария (например, увеличить лимит оперативной памяти резервируемой для билд-скрипта). Teamcity достаточно умен для того, чтобы распознать результат выполнения встроенных в жизненный цикл проекта автоматических тестов и, например, пометить билд как неудачный, если тесты были провалены. Однако, в редких случаях вы можете подсказать teamcity, где найти результаты запуска тестов и что с ними делать с помощью опций “XML Report Processing”.

Остальные настройки билд-конфигурации указывать хоть и не обязательно, но полезно. Прежде всего, мы можем настроить правила автоматического запуска билдов. По-умолчанию, для запуска билда пользователь, наделенный соответствующими правами должен зайти в панель управления teamcity, выбрать в списке доступных билд-конфигураций нужную и нажать кнопку “Run”. Помимо этого, удобным является настройка запуска билда по расписанию, например, каждый день в 23:00 или каждую пятницу в 23:00 и т.д. Количество подобных настроек времени срабатывания никак не ограничено. Еще один способ настройки автоматического запуска билдов связан с настройкой зависимости одной билд-конфигурации от другой. К пример, после того как билд-конфигурация “A” была запущена и отработала, то автоматически стартует конфигурация “B”. Еще одна полезная функция связана с отслеживанием teamcity изменений в svn-репозитории и автоматическом запуске билда. Настраивается все это на закладке “VCS Triggers”. Там вы можете указать несколько шаблонов имен файлов внутри svn-репозитория, при изменении которых teamcity начинает “предстартовый” отсчет перед запуском билда. Для того, чтобы не запускать билд, когда не все еще файлы были сохранены в репозиторий, то teamcity ждет чтобы в течении “Quiet period mode” времени не было никаких правок в репозитории и только после этого билд стартует. Не столь полезен как предыдущие режим запуска конфигурации на основании статуса предыдущего запуска билда. Т.е. если первый запуск билда был неудачен, то через, например, 60 минут teamcity автоматически перезапустит билд.

Следующая опция настройки билд-конфигурации размещена на вкладке “Dependencies” и служит для настройки списка предварительных условий, перед тем как билд будет запущен. Условно говоря, мы можем настроить три билд-конфигурации “A”, “B” и “C” так, чтобы после того как конфигурация “A” была “собрана”, то из нее будут извлечены артефакты (файлы или каталоги), которые затем будут скопированы в рабочий каталог для конфигурации “C”. Если в тот момент, когда мы запустили конфигурацию “C”, зависящую от конфигураций и артефактов “A” и “B”, еще не были готовы результаты их работы. То teamcity либо подождет завершения поставленных в очередь заданий “A” и “B” либо инициирует их запуск.

Закладка “Properties and environment variables” служит для того, чтобы передать внутрь сценария сборки проекта какие-то внешние данные. К примеру, я мог бы записать внутри нашего maven-сценария зависимость от junit-библиотеки указав ее версию так:
  1. <dependency>
  2.  <groupId>junit</groupId>
  3.  <artifactId>junit</artifactId>
  4.  <version>${JUNIT.VERSION}</version>
  5.  <scope>test</scope>
  6. </dependency>
Т.е. должна существовать какая-то переменная “${JUNIT.VERSION}” хранящая значение версии библиотеки junit. К примеру, не используя teamcity я мог бы инициировать запуск maven сценария так:
set JUNIT.VERSION=4.4
m2 clean install
Или, если билд управляется teamcity, то на закладке “ Properties and environment variables” я нажимаю кнопку “Add new variable” и указываю в появившемся диалоговом окне значение для новой переменной.

Последняя закладка “Agent Requirements” позволяет задать ряд условий, которым должны соответствовать билд-агенты для того, чтобы считаться способными выполнить билд. К примеру, мы создаем пять билд-агентов, но они не одинаковы: на одном из них есть каталог с какими-то “очень важными” библиотеками нужными для успешного завершения билда. На этот каталог указывает следующее системное свойство:
set PATH_TO_SECRET_DIR=c:/dir-with-secret
Затем я в интерфейсе teamcity на вкладке “Agent Requirements” жму кнопку “Add requirement for a variable” и указываю, что требуется на билд-агенте проверить переменную “PATH_TO_SECRET_DIR” на существование. Возможны и другие варианты, когда мы требуем, чтобы переменной не существовало или она была равна, не равна, больше, меньше, подходила по шаблону какому-то критерию.

После того как конфигурация была полностью определена, мы можем перейти на главную страницу панели управления teamcity и для созданной только что конфигурации выполнить команду запуска “Run”.



На рис. 2 показано как teamcity отображает прогресс выполнения билда, одновременно с этим примерно оценивая уже прошедшее и еще требуемое для завершения билда время (на основании статистического анализа времени выполнения предыдущих билдов). Также вы видите для билда сведения о том, какие пользователи внесли изменения в файлы проекта и даже видите информацию о версиях самих файлов. Затем после завершения билда вы можете просмотреть на вкладке “Changes” как общую информацию об измененных для этого билда файлах, так и в удобном diff-редакторе отличия между файлами (см. рис. 3).



Обратите внимание также на тот факт, что в svn-репозитории внутри каталога tags для каждого успешного билда будет появляться метка label_1, label_2 и т.д., хранящая статический “снимок” состояния проекта, который был актуален на момент запуска билда.

В следующей статье я продолжу рассказ об teamcity и посвящу его различным тонкостям: настройка извещений о завершении билдов, работа с артефактами, интеграция с IDE (intellij idea).