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

Эта статья завершит серию материалов, посвященных рассказу о том, как teamcity помогает управлять проектами разработки программного обеспечения и, в частности, автоматизирует процесс сборки проекта, запуска тестов и интегрирует эти шаги в жизненный цикл разработки приложения. Прошлые две статьи были посвящены рассказу о том, какое место занимают в ходе разработки программного обеспечения продукты класса “build management and continuous integration” вообще и teamcity в частности. Мы разобрались с основными понятиями teamcity, научились создавать билд-конфигурации и запускать их на выполнение. Этого должно быть достаточно для повседневной работы, так что сегодняшней статье осталось только “зашлифовать” некоторые нераскрытые моменты.

Прошлую статью я завершил на том, что мы создали билд-конфигурацию и запустили ее на выполнение. После того как свободный билд-агент закончил сборку maven-проекта, мы получили в свое распоряжение несколько отчетов. Во-первых, отчет о результатах запуска автоматических тестов, затем идет отчет о списке изменений в репозитории cvs/svn, которые были включены в текущую сборку. И, в конце концов, у нас в распоряжении оказался полный журнал всех сообщений, которые были сгенерированы билд-сценарием. Остался последний “смешной” вопрос: а где, собственно, находится сам результат выполнения сборки проекта, тот исполнимый файл, архив веб-приложения или “что там мы хотим отдать клиенту”? Если мы вспомним рассказ о maven, то сможем уверенно сказать, что конечный файл сборки проекта может быть найден или в локальном maven-репозитории, или в каталоге target самого проекта. То есть мы можем “руками залезть” внутрь каталога "C:\Documents and Settings\MyUserName\.m2\repository" или каталога “E:\Program_Files_2\TeamCity\buildAgent\work\5fa592b1ed40a411” и там найдем результат выполнения сборки.

Но, очевидно, что ни один из этих способов неприемлем. Есть два возможных пути дать удобный способ доступа к результатам выполнения билд- сценария, но каждый из них требует небольшого отхода от возможностей собственно teamcity и рассмотрения того, какие средства предусмотрены именно внутри maven. Как часть жизненного цикла сборки maven-проекта входит и фаза deploy – это фаза размещения сгенерированных артефактов на специальном, внешнем, сервере. В том случае, если вам достаточно собрать проект и поместить результат сборки в локальный репозиторий, используется команда “m2 clean install”. В случае, если вы хотите скопировать результат сборки на удаленный сервер, используйте команду “m2 clean deploy” (естественно, что вызов deploy включает в себя и фазу install). Теперь нам осталось разобраться с тем, как подсказать maven-у расположение удаленного репозитория, как сообщить имя и пароль для доступа к нему.

Начнем с того, что внутри pom.xml файла нужно добавить новую секцию distributionManagement, указав в ней адрес ftp-сервера. Если вы ни разу еще не работали и не знакомы с каким-либо из ftp-серверов, то я могу порекомендовать filezilla (http://sourceforge.net/projects/filezilla/) – бесплатный, простой в настройке и широко известный. Возвращаясь к настройке pom.xml файла: затем в секции build сразу после настройки плагина, выполняющего компиляцию проекта, я подключил еще и плагин “ wagon-ftp”, умеющий работать с ftp-протоколом:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
blackzorro
testartifact1
jar
1.0
Simple Maven 2 Artifact
http://maven.apache.org


junit
junit
4.4
test





maven-compiler-plugin

1.5
1.5





org.apache.maven.wagon
wagon-ftp
1.0-alpha-6






ftp-repository
ftp://center/m2-repo
default




Предполагается, что ftp-сервер содержит каталог “m2-repo”, куда и будут складываться артефакты. Последний штрих связан с настройкой учетной записи, используемой для подключения к ftp-серверу. Для этого я отредактировал файл settings.xml, добавив в секцию “servers” имя и пароль пользователя. Обратите внимание на то, что и в файле pom.xml, и в файле settings.xml я использовал одинаковое имя репозитория “ftp-repository”, чтобы maven смог между ними поставить соответствие.



ftp-repository
vasyano
secret



После того как была выполнена команда “m2 clean deploy”, на ftp-сервере появится следующая иерархия файлов "m2-repo\blackzorro\testartifact1\1.0\testartifact1-1.0.jar". Как видите, файл артефакта был сохранен по стандартным правилам maven в каталоги с именами сначала группы артефактов, затем каталога с названием самого проекта-артефакта и, наконец, каталог с номером версии проекта. Обратите внимание еще раз на файл pom.xml и, в частности, на строку “default” при регистрации репозитория. Вторым возможным значением кроме “default” является “legacy”, в этом случае файл артефакта будет сохранен под следующим именем " m2-repo\blackzorro\jars\testartifact1- 1.0.jar". Если вы обратитесь к сайту со справочной документацией maven, то сможете по аналогии настроить копирование сгенерированных артефактов не только на ftp-сервер, но и через ssh-соединение.

Увы, но показанный выше пример ни на что более сложное, чем пример (извиняюсь за тавтологию), просто не тянет, поскольку я обошел молчанием два ключевых момента, связанных с подготовкой сборки проекта. Во-первых, как быть с нумерацией версий сборок? Вторая проблема связана с тем, что только для очень простых, учебных заданий конечный файл сборки представляет собой исполнимый jar-файл или архив веб-приложения. Гораздо чаще сборка – это архив, например, zip, со сложной структурой, в состав которого входят и jar-файлы приложения, и каталоги со справочной документацией, и каталоги с библиотеками, и всевозможные инсталляционные сценарии и т.д. Что касается управления упаковкой проекта, то я могу посоветовать обратиться, прежде всего, к восьмой статье в моей серии, рассказывающей о maven, а также к справочной документации на официальном сайте maven по плагину “maven-assembly-plugin”.

Так как задача упаковки проекта слабо связана с настройкой интеграции teamcity и maven, то я не буду подробно на ней останавливаться и сразу перейду к вопросу правильной нумерации версий проекта. Напомню, что версия артефакта (а следовательно, и имя файла, под которым он будет сохранен), например, “1.2.67”, состоит из двух частей. Последняя цифра версии – это всегда номер сборки, т.е.“67” – номер билда, а предшествующая ему часть кодирует, собственно, номер версии приложения (здесь это “1.2”). Если с первой частью версии приложения вопросов нет, и мы должны ее явно указать внутри pom.xml файла:
1.0

то вот с номером билда обойтись средствами только maven невозможно, поскольку сборки запускаются из teamcity, и teamcity хранит историю сборок и номера их билдов. Значит, мы должны так настроить maven и teamcity, чтобы организовать передачу между ними информации. К счастью, перед тем как выполнить запуск билда, teamcity передает внутрь maven-сценария ряд переменных, среди которых есть и “build.number”, то есть порядковый номер билда. Сначала я задал зависимость версии проекта-артефакта от переменной “version.long”:
${version.long}
Сама же переменная состоит из двух частей, и как я обещал, вторая часть равна значению служебной teamcity переменной ”build.number”:
1.0
${version.short}B${build.number}


Таким образом, после завершения билда у меня на ftp-сервере окажется файл со следующим именем: ftp://center/m2-repo/blackzorro/jars/testartifact1-1.0B10.jar, где 10 - порядковый номер билда. Небольшим недостатком показанной методики указания версии проекта является то, что при запуске билда не с помощью teamcity, а на локальной машине с помощью команды “m2 clean install” конечный файл проекта будет иметь имя “target\testartifact1-1.0Bnull.jar”. Больших проблем “поломанная версия” проекта не вызывает, но все же смотрится некрасиво. Простым способом решения является создание “умной” maven-конфигурации, которая сначала проверит доступность teamcity-переменной “build.number” и если это не так, то назначает номер версии проекта как простое число “1.0” или равной слову “local”, то есть без номера билда. К сожалению, в составе maven нет явно выделенной функциональности условных операторов, как в “настоящих языках программирования”, но можно их имитировать с помощью профилей. Напомню, что профиль в терминологии maven – это небольшая модификация жизненного цикла проекта, точнее, плагинов и их настроек, привязанных к фазам жизненного цикла. К примеру, мы можем внутри pom.xml файла с проектом определить кроме жизненного цикла по умолчанию еще и профиль ”for-customer”. Такой профиль сформирует файл проекта, уже готовый к непосредственной доставке заказчику, когда, например, в состав проекта будет внедрена справка, а компиляция проекта будет выполнена с исключением отладочной информации или с “запутыванием” кода. Обфускация (Obfuscate) - это запутывание кода программы, при котором исполнимый файл приводится к виду, сохраняющему исходную функциональность приложения, но усложняющему анализ и модификацию. Подобные меры противодействия нужны для защиты приложений от “злых” хакеров, которые ломают защиту программы. Применительно к сегодняшней статье я буду использовать профиль только лишь для того, чтобы задать другое значение переменной “version.long” в том случае, если переменная “build.number” неопределенна. Когда же запуск maven-сценария будет выполняться на локальной машине без помощи teamcity, то файл проекта будет иметь имя “target\testartifact1-local.jar”.


default-version


!build.number



local




В своей практике я использовал как показанный выше способ сохранения результатов сборки проекта на ftp-сервере, так и методику, когда файл на ftp-сервер копируется не средствами maven (точнее, плагина, отвечающего за фазу “deploy”), а с помощью специального ant-сценария. То есть я создавал в teamcity такую build-конфигурацию, которая запускала maven-проект на сборку с профилем, например, saveToFtp. Технически я должен был при создании build-конфигурации на закладке ”Build runner” в графе “Additional Maven command line parameters” вписать имя профиля, под которым нужно запустить билд, “-PsaveToFtp”. Сам же профиль определен внутри файла pom.xml, и вся его работа состоит в том, что при наступлении фазы “package” maven запускает ant-сценарий, который последовательно копирует с помощью команды “copy” файл проекта на другой компьютер по сети \\center\SharedDocs\my-app. Вторым шагом идет копирование файла проекта на ftp-сервер (команда “ftp”). Как раз для того, чтобы последняя команда отработала как требуется, мне пришлось подключить к плагину “maven-antrun-plugin” зависимость от библиотек “ant-commons-net” и “commons-net”.

saveToFtp


org.apache.maven.plugins
maven-antrun-plugin
1.2


ant
ant-commons-net
1.6.5


commons-net
commons-net
2.0



package
run



todir="\\center\SharedDocs\my-app"/>
userid="vasyano" password="secret" remotedir="/">










В отдельных случаях можно не выполнять копирование файла с результатами сборки на какой-то ftp-сервер, а попросить teamcity сохранить его как артефакт где-то внутри самого teamcity-сервера. У teamcity тоже есть понятие артефактов и по своему значению оно сходно с тем, что под артефактами понимает maven. В последующем любой пользователь может зайти через веб-интерфейс teamcity-сервера на страничку с результатами сборки и увидеть там ссылки на все файлы, полученные в ходе выполнения сборки и заявленные как артефакты. Применительно к нашему случаю я хочу зарегистрировать как артефакт файлы, находящиеся в каталоге “target”. Для этого я от имени администратора teamcity захожу на страницу редактирования свойств билд-конфигурации, затем на закладку “General Settings” и в графе “Artifact Paths” ввожу следующие две строки: target/*.jar
target/surefire-reports/**/*.* => test reports

Каждая строка состоит из двух частей, которые разделены символами “=>”. Первая часть (“target/*.jar” или “target/surefire-reports/**/*.*”) представляет собой пути к файлам или каталогам, которые мы хотим пометить как артефакты. При задании путей мы можем использовать символы подстановок, такие как * и ** (каталоги на любом уровне вложенности). Вторая же часть выражения (обратите внимание, что в первом примере она отсутствует) задает имя файла или “виртуального” подкаталога, в который teamcity скопирует файлы артефактов. Так первой строкой я попросил teamcity сохранить все файлы с расширением jar внутри подкаталога target под теми же именами, которые они имеют. А вторая строка скопировала все файлы из подкаталога “surefire-reports” в подкаталог “ test reports” (это файлы с отчетами по результатам выполнения тестов). На рис.1 я показал то, как выглядит страничка с перечнем доступных артефактов, каждый из которых вы можете загрузить к себе на компьютер. Что касается сроков хранения артефактов, равно как и хранения истории запуска билдов, то это можно настроить в панели управления teamcity на странице “Administration -> Clean-up process settings”.

Следующая часть статьи будет посвящена средствам интеграции teamcity со средами разработки. Приятно, что хотя создавшая teamcity компания jet brains разрабатывает также и среду для java-программистов под названием intellij idea, но jet brains решила не обижать невниманием также и тех программистов, кто предпочитает для работы среду IDE eclipse или даже программирует не на java, а на visual studio. Для того чтобы установить к себе на компьютер плагин teamcity, необходимо зайти в панели управления teamcity на страницу “My Settings & Tools”, и там вы увидите ряд ссылок для загрузки плагинов.

Я скачал файл “TeamCity-IDEAplugin.zip ” плагина для idea, затем распаковал содержимое архива в каталог idea/plugins и после перезапуска среды idea получил в свое распоряжение новое меню “teamcity”. Первым шагом настройки интеграции idea и teamcity является регистрация пользователя. Для этого я выбрал меню “Teamcity -> Login” и в появившемся диалоговом окне указал адрес подключения к teamcity, свое имя и пароль. Первое, что мы настроим – это система извещений о таких событиях, как запуск билда и результат его выполнения. Teamcity может посылать сообщения о перечисленных выше событиях, например, по e-mail или jabber-клиенту, но гораздо удобнее, если извещения показываются в среде разработки, так как мы получаем дополнительный функционал быстрого перехода к списку изменений, произошедших в проекте с момента прошлого билда. Итак, выбираем меню “teamcity -> Edit Notification Rules”, затем в открывшемся окне браузера вводим свое имя и пароль, чтобы попасть внутрь teamcity, и, наконец, перед нами открывается страница редактирования правил извещений.

Нас интересует закладка “IDE notifier” (см. рис. 2), где мы можем выбрать, когда teamcity пошлет нам извещение. Я выбрал события “The build is successful”, “Responsibility changes” и “The build fails”. Теперь, после того как билд будет завершен, я увижу всплывающее окошко с сообщением об этом. Более того, teamcity-плагин предоставил мне доступ к панели наблюдения за статусом билдов.

Так, на рис. 3 я показал момент, когда сборка проекта завершилась неудачей, и я решил взять на себя ответственность за этот сбой. То есть я сообщаю teamcity о том, что именно мои изменения являлись причиной сбоя. После того как я исправлю ошибку в коде и сохраню изменения в cvs|svn, я смогу попросить teamcity пометить следующий билд как содержащий исправления для предыдущего.

Как приятный бонус после установки плагина интеграции teamcity и idea, мы получаем функцию быстрого перехода из окна браузера, например, со страницы с перечнем измененных файлов в окно java-редактора. Также панель teamcity содержит функцию просмотра списка последних файлов, а еще позволяет просмотреть различия между ними с помощью удобного diff-редактора (см. рис. 4).

Крайне полезна на практике и функция “Remote Run”. Так, если я внутри редактора idea изменю какой-то файл и выберу в меню пункт “teamcity -> remote run”, то idea отправит файлы с изменениями кода не в cvs/svn-репозиторий, а непосредственно на машину с билд-агентом. На рис. 5 показан пример диалогового окна, где я настраиваю параметры Remote Run. Так, я указал, что если запуск билда с моими правками будет успешен, и ни один из тестов не будет провален, то изменения нужно автоматически сохранить и в cvs/svn-репозиторий.

На этом я завершаю рассказ о teamcity и о том, какое место он занимает в процессе управления сборкой проектов. Естественно, что три статьи серии не могут претендовать на достаточно полное описание возможностей teamcity, но я надеюсь на то, что вы поняли, зачем нужны продукты класса “Build management and continuous integration” вообще и, в частности, один из лучших представителей этого семейства – teamcity.

black-zorro@tut.by black-zorro.com


Компьютерная газета. Статья была опубликована в номере 27 за 2009 год в рубрике программирование

©1997-2022 Компьютерная газета
oJnWE3?=нD}{DfHM=|]| ,Rh٣ <Ļi՛)^l`6=Rep9oyB~{<@- $ 3?:͜i*Ifgf$;9'yUw9Z.N#ҧcxS`np^i㺔o; :_].mC[tTbH)n̳\jzskV[CMͿ v}\I?lI_ }:7„CzhrE