среда, 4 декабря 2013 г.

Интеграция Octopus Deploy и TeamCity

Octopus Deploy умеет интегрироваться как с MS Build так и с TeamCity. В первом случае используется Nuget пакет OctoPack, который позволяет формировать пакеты для деплоймента. Для TeamCity же существует плагин, который позволяет вызывать команды Octopus API.

Что нужно сделать для интеграции Octopus Deploy и TeamCity?

  1. Добавить OctoPack к проекту в Visual Studio.
  2. Добавить плагин к TeamCity 
  3. Включить Nuget сервер на TeamCity.
  4. Создать деплой шаги в Octopus.
  5. Создать дополнительные шаги в TeamCity.

Добавление OctoPack к проекту в Visual Studio

Открываем наш проект в Visual Studio и добавляем Nuget пакет OctoPack в наш проект. Теперь во время билда нашего проекта, так же будут формироваться Octopus пакеты.

Добавление плагина к TeamCity 

Скачиваем плагин с http://octopusdeploy.com/downloads и просто копируем архив в соответствующую папку на машине с TeamCity. После этого перегружаем сервисы TeamCity и TemaCity агента.
В моем случае это была папка C:\ProgramData\JetBrains\TeamCity\plugins.
Более подробное описание тут http://confluence.jetbrains.com/display/TCD8/Installing+Additional+Plugins


Включение Nuget сервера на TeamCity

Открываем консоль TeamCity и переходим в раздел Administration - NuGet Settings. Включаем Nuget Server и копируем его адрес. Далее открываем консоль Octopus Server, переходим в Configuration - NuGet и добавляем этот линк. Теперь неплохо бы проверить доступ Octopus к NuGet серверу.

Создание деплой шагов в Octopus

Для начала проверим что Octopus Deploy содержит нужные нам окружения и машины с правильными ролями. У меня создано окружение Dev с машиной WebDev, у которой роль Web. Так же у меня создан проект Web Site. 
Переходим на наш проект в список шагов и создаем новый шаг с типом "Deploy a NuGet package". Задаем следующие параметры:
  • Step name: Deploy
  • NuGet package: имя вашего проекта, который был собран с TeamCity, в моем случае это Demo
  • Deploy to roles: Web
Остальные параметры оставим пока по умолчанию.
Теперь добавим переменную "PackageDirectoryPath" с значением "c:\web". Переменные так же позволяют подменять значения в Web.config нашего сайта во время деплоймента, так мы можем установить различные значения ConnectionString для Dev и Live окружений.
Вернемся к списку шагов и обновим наш шаг Deploy, изменив значения:
  • Destination folder: #{PackageDirectoryPath}
  • Update IIS: нет
  • Site/virtual directory: $OctopusParameters["OctopusProjectName"]
Теперь добавим второй шаг типом "Run a PowerShell script" и именем "Update IIS". Сам скрипт следующий:
$siteName = $OctopusParameters["OctopusProjectName"]
$path = $OctopusParameters["PackageDirectoryPath"]
$port = 80
Import-Module webadministration
New-Website -Name $siteName -PhysicalPath $path -Force -Port $port
Start-Website -Name $siteName
trap [Exception]
{
    Write-Error $_.Exception.Message
    exit 1
}
Данный скрипт настраивает IIS для нашего веб сайта. Роль конечно же "Web"

По настройкам Octopus Deploy все, теперь можно создать релиз и задеплоить его.

Создание деплой шагов в TeamCity

Открываем консоль TeamCity и переходим в редактирование нашего проекта, для этого можно нажать на имени проекта "Web Site", а потом выбрать "Edit Project Settings". Нам нужно создать новую "Build Configuration" с именем Deploy.
VCS оставляем по умолчанию и переходим собственно к "Build Step". Задаем:
  • Runner type: OctopusDeploy: Release
  • Step name: Deploy
  • Octopus URL: адрес нашего Octopus Deploy сервера
  • API key: ключ нашего аккаунта в Octopus
  • Project: Web site
  • Release number: 1.2.5.%env.BUILD_NUMBER%
  • Deploy to: Dev
  • Wait for deployment to complete: да
Осталось добавить билд тригер, если мы хотим что бы деплоймент на Dev выполнялся после каждого успешного билда. Создаем "Finished Build Trigger" зависимого от "Web Site :: Build".

Все готово, возвращаемся на главную консоли TeamCity и запускам билд конфигурацию, в результате будут автоматически выполнятся следующие действия:
  1. Получение исходного кода из репозитория
  2. Билд веб сайт и публикация пакета на Nuget сервере
  3. Запуск всех юнит тестов
  4. Создание нового релиза в Octopus Deploy
  5. Деплой этого релиза на Dev окружение

Тем самым мы реализовали стратегию "continuous delivery".

среда, 20 ноября 2013 г.

Установка Octopus Deploy

Установка сервера Octopus Deploy

Octopus Deploy - позволит реализовать деплоймент нашего asp.net mvc приложение на существующее окружение. Он обеспечит:

  • копирование нашего пакета (будет создаваться на TeamCity) на удаленную машину с IIS
  • подмену значений в web.config
  • запуск Database migration скриптов
  • разворачивание этого пакета в определенную папку
  • настройку IIS, выполнив powershell скрипты на этой машине
  • UI для управления и мониторинга деплоймента
  • интеграцию с TeamCity и MSBuild

Для начала запускаем новую виртуалку и скачиваем инсталляцию Octopus Deploy Server c http://octopusdeploy.com/downloads, далее устанавливаем Octopus. По окончании установки, запускам визард конфигурации, он скорее всего ругнется, что не все компоненты IIS установлены. В мое случаю он просит выполнить команду для установки ISS

DISM.exe /Online /Enable-Feature /FeatureName:IIS-WebServerRole /FeatureName:IIS-WebServer /FeatureName:IIS-CommonHttpFeatures /FeatureName:IIS-StaticContent /FeatureName:IIS-DefaultDocument /FeatureName:IIS-HttpErrors /FeatureName:IIS-ASPNET /FeatureName:IIS-ASPNET45 /FeatureName:IIS-NetFxExtensibility /FeatureName:IIS-NetFxExtensibility45 /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-ISAPIFilter /FeatureName:IIS-ManagementConsole /ALL

Выполняем эту команду через Command Promt (win-R, и выполняем cmd).

Deployment Image Servicing and Management tool
Version: 6.2.9200.16384
Image Version: 6.2.9200.16384
Enabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.

Потом жмем "Check Again" и попадаем в Octopus Administration Tools, здесь задаем наши настройки. Наиболее важны вкладки Server И Web Portal, где нам нужно запустить Octopus Server сервис и Web UI. Если используем порт 80, то необходимо остановить Default Web Site.
Так же важно не забыть открыть порт в Firewall
netsh advfirewall firewall add rule name=Octopus dir=in action=allow protocol=TCP localport=80

Теперь может открыть Octopus UI, где нам предложат создать админский аккаунт. После его создания мы должны увидеть следующее.
В Octopus создаем новые окружением, например Dev и проект, например Web Site.

Подготовка нового окружения.

Мой Asp.net mvc веб сайт будет хоститься на отдельной новой виртуалке.
Что бы подготовить ее нужно выполнить следующее:
  • Установить IIS и NET 4.5
  • Удалить Default Web Site
  • Открыть порт 80 в Firewall
  • Установить Octopus Tentacle
  • Добавить наш Octopus Server в список разрешенных
Для установки IIS, опять воспользоваться командой

DISM.exe /Online /Enable-Feature /FeatureName:IIS-WebServerRole /FeatureName:IIS-WebServer /FeatureName:IIS-CommonHttpFeatures /FeatureName:IIS-StaticContent /FeatureName:IIS-DefaultDocument /FeatureName:IIS-HttpErrors /FeatureName:IIS-ASPNET /FeatureName:IIS-ASPNET45 /FeatureName:IIS-NetFxExtensibility /FeatureName:IIS-NetFxExtensibility45 /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-ISAPIFilter /FeatureName:IIS-ManagementConsole /ALL

или powershell скриптом

Install-WindowsFeature web-server, Web-Net-Ext45, Web-Asp-Net45

Порт открываем командой

netsh advfirewall firewall add rule name=WebSite dir=in action=allow protocol=TCP localport=80

Для установки агента Octopus Tentacle качаем его с http://octopusdeploy.com/downloads
После установки tentacle запускается визард, где нам нужно указать Thumbprint нашего сервера (его можно найти по адресу OCTOPUS_SERVER/configuration/certificates) и запустить Tentacle Service.
А так же нужно открыть порт 10933 для того что бы Octopus Server мог давать команды Octopus Tentacle 

netsh advfirewall firewall add rule name=Octopus dir=in action=allow protocol=TCP localport=10933

Теперь наш Dev сервер готов к деплойменту на него нашего приложения, осталось добавить его на Octopus Server.

Возвращаемся на Octopus Server UI, вкладка environments и добавляем новую машину в окружение Dev
Thumbprint можно взять в Tentacle Administration Tool.
Для проверки соединения между сервером а агентом нужно нажить кнопку "Check health" в верхнем правом углу.

Если все хорошо, то получаем подобную картину
Автоматизированный процесс установки описан Tentacle здесь http://octopusdeploy.com/documentation/configuration/installation

В следующем посте я расскажу об интеграции Octopus Deploy и Temacity.

пятница, 15 ноября 2013 г.

TeamCity настройка билд процесса для ASP.NET веб сайта.

TeamCity установлен, теперь займемся его настройкой.
Для начала создаем новый проект.

Далее создаем новый билд, это кнопка "Create build configuration".
На странице "General Settings" задаем следующие параметры:
  • Name: "Build"
  • Description "Build and run unit tests"
остальные параметры по умолчанию и нажимаем кнопку "VCS settings".

На странице "Version Control Settings" нажимаем кнопку "Create and attach new VCS root". Я к примеру использую GIT хранилище, задаем следующие параметры:
  • Type of VCS: Git
  • VCS root name: MyGit
  • Fetch URL: git@git.myserver.git (путь к вашему хранилищу)
Authentication Settings: выбираем метод аутентификации на GIT сервере, я использую авторизацию по приватному ключу, сам ключ нужно скопировать TeamCity сервер. Т.е. задаем
  • Authentication method: Private Key
  • Private key path: C:\Keys\RomanDemo
Все остальные поля оставляем по умолчанию и жмем "Test connection", если все в порядке, сохраняем наше подключении к GIT серверу. 
Мы должны увидеть сообщение:
VCS root created.

Следующий шаг "Add Build Step", так как мы будем билдить NET приложение, то мы используем MSBuild, следовательно выбираем такой же "Runner type". Далее заполняем следующие поля:
  • Build file path: DemoSolution.sln - имя солюшена нашего приложения
  • MSBuild version: версия используемого фреймворка.
Жмем "Save" - мы создали автоматический билд нашего приложения при каждом комите, теперь можем вручную запустить билд с помощью кнопки "Run". Что бы посмотреть прогресс билда и результаты нам нужно перейти на главную страницу TeamCity. Для этого можно надать ссылку "Projects" в верхнем левом углу.

К сожалению наш проект не билдится:
Что бы понять в чем проблема достаточно нажать на самой ошибке. Наша проблема в том что проект использует функцию Nuget Restore

  • C:\TeamCity\buildAgent\work\ad79b1c1983611f5\.nuget\NuGet.targets(88, 9): Package restore is disabled by default. To give consent, open the Visual Studio Options dialog, click on Package Manager node and check 'Allow NuGet to download missing packages during build.' You can also give consent by setting the environment variable 'EnableNuGetPackageRestore' to 'true'.
  • Решения два: добавить переменную окружения или создать дополнительный билд шаг, который восстановит все пакеты.

  • Возвращаемся в редактирование билд конфигурации
  • Первый вариант - это добавление переменной окружения. 
  • Переходим в 7-й шаг Build Parameters и создаем новую переменную окружения env.EnableNuGetPackageRestore с значением "true"

Второй вариант - это добавить предварительный билд шаг
Переходим во 2-й шаг Build Steps и создаем новый шаг с типом "Command Line". Задаем параметры
  • Step name: "Restore" 
  • Custom script: .nuget\nuget.exe restore DemoSolution.sln. 
Сохраняем новый шаг и ставим его первым перед собственно билдом.
*команда Restore появилась недавно и возможно вам придется обновить nuget в вашем проекте.

Запускаем наш исправленный билд снова. И снова ошибка
Compilation error: Demo\Demo.csproj
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" was not found
Проблема в том что на нашем билд сервере не стоит Visual Studio и нет содержимого папки "Microsoft.WebApplication.targets", самое простое решение это скопировать эту папку (C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio) с компьютера с установленной студией на билд сервер.
Другой вариант это установить на билд сервере Microsoft Visual Studio 2012 Shell (Integrated) Redistributable Package.

После решения этой проблемы вновь запускаем билд и бинго билд прошел успешно.
Теперь добавим запуск юнит тестов. Переходим в редактирование билд конфигурации и добавляем новый билд шаг с типом "NUnit" и параметрами:
  • Step name: Run unit tests
  • .NET Runtime: v4.0
  • Run tests from: **\bin\debug\*UnitTest*.dll
Сохраняем этот шаг, как последний и после запуска теста, мы увидим количество пройденных тестов, если хоть один тест упадет, наш билд будет считаться проваленным.

В итоге мы реализовали Continuous integration процесс при помощи Teamcity. Сервер будет автоматически проверять новые версии вашего проекта, билдить его и запускать юнит тесты.

Далее я расскажу как реализовать деплоймент процесс при помощи Octopus Deploy.

пятница, 8 ноября 2013 г.

Установка TeamCity

TeamCity - это один из инструментов, который позволяет реализовать Continuous Integration процесс. Как по мне TeamCity довольно не сложно изучить и настроить. Но как и везде есть нюансы, особенно в настройке билд процеcса для NET 4.5.

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

Я буду разворачивать TeamCity на Windows Server 2012 64Bit, которой хостится на AWS. 

Для начала я запустил новую виртуалку и скачал на нее TeamCity  8.0.4
http://www.jetbrains.com/teamcity/download/index.html

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

Все TeamCity установлен и готов к использованию.

Для того что бы к консоле можно было достучаться с других компьютеров, нужно открыть порт, это можно сделать из командной строки

netsh advfirewall firewall add rule name=Teamcity dir=in action=allow protocol=TCP localport=80

В следующем посте я расскажу, как настроить билд процесс для ASP.NET веб сайта.

четверг, 7 ноября 2013 г.

Что такое Continuous Integration?


  • Continuous Integration (CI) - это процесс постоянного запуска билда вашего приложения после каждого сохранения исходного кода в репозитории, с последующим запуском Unit тестов.
  • Continuous delivery - это когда добавляется деплоймент приложения на тестовое окружение с последующим запуском интеграционных и UI тестов.
  • Continuous deployment - ко всему предыдущему добавляем, создание при помощи скриптов, нового окружения. Что в конечном счете позволяет создать 1-click процесс для деплоймента приложения из кода на продакшен сервер.
Для выполнения деплоймента веб приложения на окружение нужно выполнить следующие шаги:
  1. Получить исходный код из репозитория.
  2. Выполнить билд приложения.
  3. Запустить все Unit тесты.
  4. Сформировать пакет, которые будет содержать готовое приложение.
  5. Подготовить существующее окружение (staging) или создать новое.
  6. Выполнить деплоймент пакета с приложением на окружение.
  7. Запустить интеграционные тесты.
  8. Запустить UI тесты.
Первые три шага легко реализуются любым популярным CI (TeanCity, Jenkins, Team Foundation Server и CruiseControl.NET).

Шаги 4-6 реализовать несколько сложнее, если мы говорим об .Net, то для их реализации можно использовать инструмент Octopus Deploy.

В следующих постах, я покажу как можно установить TeamCity и Octopus Deploy, а так же что нужно сделать для их настройке. В результате получим CI процесс от кода до протестированного приложение на Dev окружении.

Установка TeamCity
TeamCity настройка билд процесса для ASP.NET веб сайта
Установка Octopus Deploy
Интеграция Octopus Deploy и TeamCity

вторник, 14 декабря 2010 г.

5 правил для хороших тестов

В книге "Чистый код", красиво описываются требования к тестам.

Чистые тесты должны обладать пятью характеристиками, названия которых образуют приведенное сокращение FIRST

  • Быстрота (Fast). Тесты должны выполняться быстро. Если тесты выполняются медленно, вам не захочется часто запускать их. Без частого запуска тестов проблемы не будут выявляться на достаточно ранней стадии, когда они особенно легко исправляются. В итоге вы уже не так спокойно относитесь к чистке своего кода, и со временем код начинает загнивать.
  • Независимость (Independent). Тесты не должны зависеть друг от друга. Один тест не должен создавать условия для выполнения следующего теста. Все тесты должны выполняться независимо и в любом порядке на ваше усмотрение. Если тесты зависят друг от друга, то при первом отказе возникает целый каскад сбоев, который усложняет диагностику и скрывает дефекты в зависимых тестах.
  • Повторяемость (Repeatable). Тесты должны давать повторяемые результаты в любой среде. Вы должны иметь возможность выполнить тесты в среде реальной эксплуатации, в среде тестирования или на ващем ноутбуке во время возвращения домой с работы. Если ваши тесты не будут давать однозначных результатов в любых условиях, вы всегда сможете найти отговорку для объяснения неудач. Также вы лишитесь возможности проводить тестирование, если нужная среда недоступна.
  • Очевидность (Self-Validating). Результатом выполнения теста должен быть логический признак. Тест либо прошел, либо не прошел. Чтобы узнать результат, пользователь не должен читать журнальный файл. Не заставляйте его вручную сравнивать два разных текстовых файла. Если результат теста не очевиден, то отказы приобретают субъективный характер, а выполнение тестов может потребовать долгой ручной обработки данных
  • Своевременность (Timely). Тесты должны создаваться своевременно. Модульные тесты пишутся непосредственно перед кодом продукта, обеспечивающим их прохождение. Если вы пишете тесты после кода продукта, вы можете решить, что тестирование кода продукта создает слишком много трудностей, а все из-за того, что удобство тестирования не учитывалось при проектировании кода продукта.

среда, 24 ноября 2010 г.

Создание пользовательского логотипа в SSRS отчете.

Недавно передо мной встала задача вместо статического логотипа в SQL server reporting service сделать показ лого, которое храниться базе. Следует отметить, что отчет хранится внутри приложения, не на сервере SSRS.

Погуглив я нашел три способа сделать это:
1) Передавать картинку в параметрах
2) Использовать дополнительный DataSource к базе в отчете
3) Создать SubReport с лого и включать его во все репорты.

По идее наиболее просто это создать сабрепорт и использовать его во всех отчетах, но оказалось, что его нельзя вставить в header отчета.

С DataSource тоже не сразу получилось, оказывается контрол Image в заголовке не может ссылаться на DataSource. MSDN подсказал финт ушами - создаем невидимый textbox, он вычитывает данные из DataSource, а картинка в заголовке уже берет данные из textbox. Реализовал эту стратегию, но кода получилось довольно много.

В результате наиболее выгодной стратегий оказалось передавать картинку в параметре. Но тут тоже ограничение, пареметр не может быть бинарным, поэтому картинку нужно вначале перекодировать в Base64, а потом уже в отчете раскодировать обратно.

Формируем параметр:

byte[] logo = GetLogoFromDB();
string paramLogo = Convert.ToBase64String(logo);

Передаем его в отчет:

ReportViewer.LocalReport.SetParameters(
new List<ReportParameter>()
{
new ReportParameter("logo", paramLogo )
});

В самом отчете создаем параметр "logo" а для картинки ставим
value=System.Convert.FromBase64String(Parameters!logo.Value)

В итоге кода не очень много и получаем наше кастомное лого в отчете.

Описание решений по работе с картинками в SSRS:
Images (Report Builder 3.0 and SSRS)
http://technet.microsoft.com/en-us/library/dd239394.aspx