среда, 8 сентября 2010 г.

Cruise Control .Net и развертывание SharePoint-продуктов

Благодаря Cruise Control .Net (далее - CCNet) недавно удалось решить несколько важных проблем на работе, поэтому спешу поделиться!


Кто не знает, CCNet - это программный комплекс, предназначенный для непрерывной интеграции, т.е. для организации постоянных сборок продукта (например, каждый час). Непрерывная интеграция в простейшем виде позволяет отследить людей, которые коммитят не компилящийся код. Если же немного повозиться с настройками - у вас в руках окажется мощнейший инструмент для автоматизированного тестирования. К тому же, бесплатный...

Ниже речь пойдет о применении CCNet для непрерывной интеграции большого коробочного продукта под SharePoint.

Проблема развертывания

У SharePoint, вообще говоря, есть немало различных проблем. Все они решаемы, но некоторые заставляют порядком почесать репу. В частности, проблема развертывания некоего коробочного продукта на целевую систему продолжает быть весьма актуальной. Особенно, если продукт большой, и предполагает наличие кучи wsp-файлов, а также несколько Windows-утилит и/или служб. Решение задачи развертывания традиционно возлагают на установщик продукта.

Довольно очевидна мысль, что установщик тоже нуждается в тестировании. Вообще, я бы сказал даже, что установщик прежде всего нуждается в тестировании, постоянном и всестороннем. Ведь именно он скачивается клиентами, которые продукт купили. Причем, скачивается многократно - ведь продукт не стоит на месте, а развивается и требует обновлений.

Нужна капитальная уверенность, что клиенты не найдут в установщике сюрпризов. Потому что это деньги и престиж компании в целом, а с такими вещами не шутят.

Установщик SharePoint-продукта

А между тем, установщик SharePoint-продукта часто оказывается весьма сложным. К примеру, действующий установщик нашего продукта состоит из двух частей:
  1. Мастер установки сделан в виде стандартного Setup-проекта, т.е. представляет собой msi-файл, и служит для установки на целевой системе Windows-служб и утилит, документации, а также для установки мастера настройки.
  2. Мастер настройки базируется на практически полностью переписанном SharePoint Installer'е, и осуществляет развертывание собственно портала и веб-частей, активацию фич и прочая. Он состоит из кучи dll-ек, wsp-шек, ну и собственно exe-шника.
Впрочем, подробное описание установщика выходит за рамки данной статьи (и я не уверен, что буду про него писать, т.к. давно мечтаю перевести всё это безобразие на мой любимый WiX). Он упомянут здесь лишь для того, чтобы дать читателям осознать, что такую сложную махину нужно обязательно тестировать, и чем чаще - тем лучше.

Тестирование развертывания

Давайте посмотрим, что нужно сделать, чтобы протестировать развертывание SharePoint-продукта вручную:
  1. Скомпилировать солюшен целиком, чтобы обеспечить наиболее свежую версию кода
  2. Собрать WSP-файлы. В IDE это делается правым щелчком по SharePoint-проекту, и выбором пункта Package. Таких проектов может быть много.
  3. Собрать мастер настройки и все остальное, что еще нужно ставить на целевую систему
  4. Собрать Setup-проекты (их несколько для разных версий продукта и для разных языков), получив в результате MSI-файлы
  5. Скопировать MSI на целевую машину (обычно это одна или несколько виртуалок для тестирования)
  6. Запустить мастер установки
  7. Запустить мастер настройки
  8. Запустить веб-тесты, чтобы проверить, что портал хоть немного работает...
Здесь опущены Unit-тесты, но сложности в том, чтобы их прогнать, как раз нет (их гораздо сложнее написать нормально). Основная сложность заключается именно в тестировании установщика.

Я думаю, для всех очевидно, что некоторые из перечисленных действий занимают немало времени. Вручную процесс тестирования развертывания или даже просто сборки установщиков превращается в довольно нудную и неоправданно сложную задачу. Фактически, у нас в офисе вручную установщик собирать умело четверо или пятеро, остальные же ходили и требовали собрать им свежий пакет, поскольку самим им разбираться долго... Согласитесь, непорядок!

Настройка Cruise Control .Net

Давайте попробуем автоматизировать все 8 упомянутых выше действий с помощью CCNet.

Пункт первый - билд солюшена. Самое простое. Обычный код для сборки солюшена выглядит примерно следующим образом (поместить внутрь тега <tasks> в файле конфигурации config.xml):
<msbuild>
  <description>Build and test: Solution</description>
  <executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
  <workingDirectory>C:\path\to\solution</workingDirectory>
  <projectFile>Product.sln</projectFile>
  <buildArgs>/p:Configuration=Debug</buildArgs>
  <targets>Build</targets>
  <timeout>600</timeout>
</msbuild>
Более подробную информацию о теге <msbuild> можно прочитать в статье MSBuildTask.

Следующий этап - это Package и получение WSP-файлов. Однако у солюшенов нет таргета "Package". Придется билдить каждый из SharePoint'овских проектов. Т.е. для каждого из проектов предстоит создать примерно такую конструкцию:
<msbuild>
  <description>Package: SharepointProject1</description> 
  <executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
  <workingDirectory>C:\path\to\sharepointproject1</workingDirectory> 
  <projectFile>Product.SharePointProject1.csproj</projectFile>
  <buildArgs>/p:Configuration=Debug</buildArgs>
  <targets>Package</targets>
  <timeout>60</timeout>
</msbuild>
Если вам нужно передавать проектам какие-то дополнительные переменные, то это делается добавлением ";<propertyname>=<propertyvalue>" в параметр "p" тега <buildArgs>. Например, мне потребовалось задавать SolutionDir:
<buildArgs>/p:Configuration=Debug;SolutionDir=C:\path\to\solution</buildArgs>
Также, довольно полезно передавать OutputDir, это может помочь избежать лишних копирований файлов с помощью PostBuild-эвентов или с помощью bat-файлов.

Чтобы упростить последующие изменения config.xml, рекомендую выносить все повторяющиеся элементы в параметры конфигурации CCNet. К примеру, можно вынести название собираемой конфигурации, чтобы позже иметь возможность быстро переключаться между Release- и Debug-сборками.

Чтобы объявить параметр, нужно поместить примерно следующий код в секцию <parameters>:
<textParameter>
  <name>Configuration</name>
  <display>Configuration to build</display>
  <default>Debug</default>
  <required>false</required>
</textParameter>
Теперь, этот параметр можно использовать:
<buildArgs>/p:Configuration=$Configuration</buildArgs>
По плану, теперь нужно собрать MSI-файлы. К сожалению, стандартные майкрософтовские Setup-проекты не поддерживаются MSBuild'ом. Их компиляция производится непосредственно визуальной средой (devenv.exe). Тут нам поможет другой вид задачи CCNet - ExecutableTask.
<exec>
  <baseDirectory>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE</baseDirectory>
  <executable>devenv.exe</executable>
  <buildArgs>/Rebuild Debug /Project C:\path\to\setupproject.vdproj</buildArgs>
  <buildTimeoutSeconds>120</buildTimeoutSeconds>
</exec>
Таким же образом можно запускать любые bat-файлы или exe-шники, которые могут понадобиться в процессе сборки. Именно с помощью тэга <exec> реализуется следующая наша задача - копирование MSI-файлов на целевую машину.

Лучше всего развертывать на некие тестовые виртуалки. Причем, чаще всего подразумевается сразу несколько виртуалок с различными параметрами. Однако, обсуждение удаленного запуска установщиков выходит за рамки данной статьи. Поэтому, для простоты, будем развертывать на сервере.

Судя по справке, для запуска в тихом режиме msi нужно выполнить msiexec с ключом /qn. Сделаем это через ExecutableTask:
<exec>
  <baseDirectory>C:\Windows\system32\</baseDirectory>
  <executable>msiexec.exe</executable>
  <buildArgs>/qn /i C:\path\to\product.msi</buildArgs>
  <buildTimeoutSeconds>600</buildTimeoutSeconds>
</exec>
Мастер настройки в нашем варианте тоже можно запустить в silent-режиме, указав дополнительно, в качестве параметров:
  • Url веб-приложения
  • Логин администратора
  • Email администратора
CCNet будет ждать выполнения каждой из задач развертывания, и текущая выполняемая задача отображается в удобном окошке "Current Status" (F4 в CCTray). В случае ошибок, ненулевой код возврата (возвращаемый через Environment.Exit(int ExitCode)) будет для CCNet сигналом, что задача завершилась неудачно, и билд провален.

Да, всё что вы выводите в консоль - потом можно будет увидеть в логе CCNet. Так что, система очень логична и весьма удобна.

Наконец, последний пункт - запуск веб-тестов, - может осуществляться через MSBuildTask (при использовании студийных веб-тестов), или же через ExecutableTask (если вы используете стороннюю систему для тестирования веб-страниц). Это уж как вам удобно. А у меня - на сегодня всё!

P.S. Желаю вам, уважаемые читатели, автоматизировать. И не только клиентов, но и собственный процесс разработки - тоже.

Комментариев нет:

Отправить комментарий

Внимание! Реклама и прочий спам будут беспощадно удаляться.

Примечание. Отправлять комментарии могут только участники этого блога.