2 роки тому в статті "Continuous Delivery & Sitecore: наша реалізація "я представляв нашу систему автоматичної доставки веб-додатків заснованих на Sitecore. Це були перші маленькі кроки в напрямку світу повної автоматизації.
За минулий час проект не тільки не помер, але розрісся і заматюкав. Більш того, він все ще розвивається і вбирає в себе все більше і більше інструментів і можливостей. Мабуть, єдине, що залишилося без змін - це система контролю версій (GIT) і система гілки.
Великі зміни, що спіткали проект (на кожному я зупинюся докладно):
- Доставка через SSH є основною тільки для проектів, що живуть на Linux і Windows 2003. Проекти, які хостяться на Windows 2008 R2 і вище, використовують Web deploy.
- Оскільки крім веб-програм на CMS Sitecore, ми почали розробляти на Umbraco, Episerver і просто ASP.NET веб-програми, сервіси і програми - тепер CD працює також і з ними
- Внутрішня Nuget галерея і оновлення розроблюваних нами open-source бібліотек на Nuget.org також доставляється за допомогою TeamCity
SSH доставка Linux php проектів
Насправді тут все простіше простого. Оскільки PHP не потребує компіляції, доставка полягає в тому, щоб забрати вихідні з Гіта, і, підчепившись по SSH до цільового сервера - залити їх.
У TeamCity для це є спеціальний плагін - deploy-runner, який, власне кажучи, і займається всією доставкою. У майбутньому, до даного типу білдів ми плануємо причепити інтеграційні та юніт тести. На даний момент використовуються тільки для внутрішнього тестування.
Nuget, SymbolSource, упаковка і оновлення
Всередині нашої мережі ми розгорнули Nuget галерею (форк від https://github.com/NuGet/NuGetGallery), SymbolSource сервер для цієї галереї (http://www.xavierdecoster.com/setting-up-your-own-symbolsource-server-step-by-step). Так як це також веб-додатки - Teamcity відповідає не тільки за їх наповнення, але і за їх оновлення (стежить за нашими форками репозиторіїв, і з оновлення форка - доставляє оновлення на веб-додаток за допомогою описаних далі кроків).
Також TeamCity відповідає за публікацію Nuget пакетів в галерею (як внутрішню, так і зовнішню), оновлюючи пакети за допомогою вбудованих в TeamCity інструментів для упаковки і публікації пакетів. Також кожен пакет публікується у відповідну галерею SymbolSource (внутрішню або Symbolsource.org).
MsBuild, MsDeploy і все що крутиться навколо...
Власне кажучи, сама доставка і все, що з нею пов'язано.
Хотілося б сказати кілька слів про MsDeploy і про причину відходу від SSH. Незважаючи на те, що доставка по SSH відбувається досить швидко, підготовчі операції вимагають багато часу і дорогих дискових операцій. Плюс до всього, ми завжди в будь-який білд повинні або самі займатися диференціацією файлів для доставки (з тим, щоб зменшити розмір пакета, що відправляється), або ж завжди доставляти весь додаток (що не зовсім позитивно відображається на опублікованому пакеті). Якщо ж взяти MsDeploy, який викликається засобами Visual Studio або MsBuild - то доставкою файлів у веб-додаток займається MsDeploy, він же оцінює - чи потрібно оновлювати/залишати конкретний файл, що позитивно відображається на швидкості доставки. Також, у налаштуваннях за замовчуванням, MsDeploy на себе бере і наведення порядку - якщо в IDE файл був вилучений/виключений - то і в цільовому веб-додатку він не потрібен.
Для забезпечення стабільної і керованої роботи доставки - весь процес крутитися навколо MsBuild движку, поведінкою якого управляє набір імпортованих проектів (targets файлів), уніфікованих за виконуваними процедурами і відрізняються лише за типом проекту (Sitecore, Umbraco, Episerver або веб-додаток без CMS).
На target файлах я зупинюся детальніше...
Sitecore
Файл Sitecore.targets описує такі кроки:
- Підготовка програми до доставки логічних структур в базу даних - публікація конфігураційного файлу, який дозволяє використання будь-яких символів і відключає найбільш ресурсомісткі операції, що проводяться Sitecore при паблішингу. Цей крок вимагає перезапуску програми і тому викликається тільки в тому випадку, якщо у нас є що доставляти в базу даних
- Пожвавлення програми за допомогою Wget після рестарту (по суті, просто запит головної сторінки сайту)
- Додавання збірки останньої версії CI до програми
- Статичну трансформацію web.config файлу, для прибирання сміття, яке залишається в temp теці після доставки, засобами самого Sitecore
- Імпорт sharedtargets файлу, який відповідає за всі інші операції під час білда, за допомогою своїх таргетів. А черговість виконання цілей в sharedtargets файлі управляється за допомогою AfterTargets і BeforeTatgets директив.
- Які теки видаляти під час білда програми (список можна розширювати в csproj файлі самої програми) - це необхідно через те, що ми не використовуємо самоочистку файлів (SkipExtraFilesOnServer = true), для того, щоб не очищати контентні файли, потенційно створені додатком
EpiServer
Episerver.targets файл описує наступні кроки і вимоги до доставки:
- Додавання збірки останньої версії CI у програмі
- Імпорт sharedtargets файлу, який відповідає за всі інші операції під час білда, за допомогою своїх таргетів. А черговість виконання цілей в sharedtargets файлі управляється за допомогою AfterTargets і BeforeTatgets директив.
- Які теки вилучати під час білда програми
Umbraco
Umbraco.targets файл описує наступні кроки і вимоги до доставки:
- Додавання збірки останньої версії CI у програмі
- Які теки вилучати під час білда програми
- Імпорт sharedtargets файлу, який відповідає за всі інші операції під час білда, за допомогою своїх таргетів. А черговість виконання цілей в sharedtargets файлі управляється за допомогою AfterTargets і BeforeTatgets директив.
- Оновлення версії програми в ClientDependency.config (Umbraco хитро кешує статичні ресурси)
Сам білд
Всі білди уніфіковані і можуть відрізнятися лише за вимогами CMS або споживача. Тут я постараюся розібрати всі кроки по порядку (в дужках на початку опису кроку буду вказувати, якщо даний крок специфічний для якогось таргета)
- Інформаційний e-mail, що відсилається групі про те, що білд запускається. Містить таку інформацію:
- для якого проекту і якого середовища запускається білд
- хто запустив білд
- які зміни включено до білда (коментар до чекін у репозиторій, якщо коментар починається з # номер - то # номер обрамляється посиланням на запит у нашій трекінговій системі)
- (Sitecore) Перевірка, чи є в білді пекеджі (логічні елементи бази даних Sitecore для доставки). Якщо є - оновлюємо програму (покласти спеціальний конфігураційний файл, оновить CI збірку) і оживлюємо її.
- (Sitecore) Доставка пекеджів за допомогою WCF сервісу
- (Sitecore) Пабліш за допомогою WCF сервісу
- (Microsoft Network Load Balancer) Якщо додаток хоститься на декількох серверах, і трафік балансується за допомогою Microsoft NLB - то в цьому кроці ми вимикаємо додаток з балансування за допомогою Drainstop (новий трафік на додаток не потрапляє. Закінчуємо обслуговування тих користувачів, що були на момент початку Drainstop)
- Доставка App_offline.htm в корінь програми (щоб користувачі не лякалися помилок) і відключення сервісів хмарного моніторингу (щоб Uptime не падав, оскільки ASP.NET додаток з App_offline.htm в корені, хоч і демонструє красиву картинку і напис, але повертає HTTP статус 503). Які сервіси моніторингу відключати - контролюється параметрами білда
- Nuget restore - незважаючи на те, що можна і потрібно включати Nuget restore на рівні солюшену, деякі збірки змінюють сам процес білда (наприклад, Microsoft.Bcl.Build)
- MsBuild Publish - тут те і відбувається вся магія...
Я не буду описувати все, що робить MsBuild, а лише опишу ті зміни, що вносяться sharedtargets.target файлом.
1) Якщо специфічний для програми target файл додає CI файли - вони додаються на самому початку (ми їх віртуально позначаємо як Content з метою даними CopyToOutputDirectory = Always)
2) AddVersionTxt - додає в корінь веб-додаток файл version.txt, який містить в собі номер білда і дату (зручно для тестерів і третіх осіб - що зараз опубліковано). У Sitecore воно ще й в інформації про додаток видно
3) (Sitecore) Статичний трансформ для вилучення файлів з temp теки
4) Encrypt - якщо у програмі до налаштованої теки додано RSA ключ, і прапор EncryptWebConfigOnTeamcityBuild = true, то під час білда TeamCity зашифрує appSettings і connec Strings секції у web.config (можна додати ще sprotings)
5) Якщо в програмі використовується додаткова база даних - то викликається SqlUpdaterSupportTarget. Так само як і другий крок, він перевіряє, чи були зміни в сконфігурованій папці і якщо були - засобами MsDeploy оновлює сконфігуровану в TeamCity базу даних. Вміє працювати як з MSSQL, так і з MySQL. Поки що вміє оновлювати лише одну базу даних. Якщо їх декілька - треба додавати додатковий крок перед видаленням App_offline
- (EpiServer) Оскільки Episerver складає файли, необхідні для CMS поза рутою веб програми до теки AppData і ходить до них через VirualPathProvider - ми повинні перевірити, чи були зміни в цій теці, і якщо були - то теж залити їх на сервер
- Видалення App_offline, пожвавлення програми і включення сервісів моніторингу назад
- Пожвавлення веб-додатку - Wget пробігає по всіх сторінках першого рівня сайтів, зазначених у конфігурації білда.
Незабаром, замість конфігурації білда, планується це завдання винести в WCF сервіс.
Також, на цьому кроці, зберігаються числові значення (скільки часу на нього знадобилося). Надалі будемо проводити досить приблизний аналіз продуктивності веб-додатку (ламерська, але метрика:) )
- Аналіз опублікованого web.config за допомогою OWASP (репорт доступний у звітах Teamcity)
- Стандартні перевірки веб-програми і відсилання email з результатами перевірок і білда групі.
На даний момент, до стандартних перевірок входить тільки перевірка наявності robots.txt, його аналізу за допомогою парсера https://code.google.com/p/robotstxt/, а також валідація sitemap.xml.
Цей крок повинен і буде розширюватися різного роду інтеграційними та юніт-тестами
Крім веб-додатків, ми також розробляємо додаткові сервіси для Windows. І їх також треба доставляти...
Для цього теж є окремий білд, що складається з наступних кроків:
- Nuget Restore
- Білд за допомогою Visual Studio (Visual Studio (sln) runner)
- Зупинка і вилучення серверів на цільовому сервері за допомогою MsDeploy runCommand провайдера
- Заливка файлів за допомогою MsDeploy
- Встановлення серверів на цільовому сервері за допомогою MsDeploy runCommand
Ну і ще один білд необхідний, щоб TeamCity побудував для себе всі ті інструменти, які описані вище. Вони всі зібрані в один солюшень, і за його зміною, запускається білд, що складається з наступних кроків:
- Nuget Restore
- Visual Studio Build
- Powershell скрипт, який розкладає результати кроку два по всіх агентах
Крім даних білдів, що здійснюють доставку коду, існує ще один TeamCity білд - не має відношення до доставки коду, а є просто сервісним. Він складається з двох кроків і єдина його мета - викликати recycle процесу, що обслуговує веб-додаток. Потрібен він для того, щоб мати можливість швидко перезапустити веб-додаток
- MsBuild, за допомогою вбудованого в MsDeploy провайдера recycleApp, викликає рестарт програми
- Wget у режимі павука завантажує першу сторінку веб-програми (для його швидкого пожвавлення)
Даний «білд» викликається не часто, так як це крайня міра.
Візуалізація
Як фінальний штрих, за допомогою open-source тула Gource, я додав візуалізацію розробки CI: