Перейти к содержимому

Teamcity: Трансформация web.config развернутого приложения

Я – большой фанат , автоматической доставки, развертывания и любой автоматизации. Как правило, я имею дело с доставкой разработанных нами приложений, но в данном посте речь пойдет о доставке дополнительного функционала в “чужое”, “коробочное” веб-приложение, развернутое на нашем сервере.

Итак, исходные данные. В наличии имеется:

  • Teamcity
  • Пачка разработанного функционала (описано тут - http://habrahabr.ru/post/249523/)
  • (тот самый “чужой”, “коробочный” продукт)
  • Некое количество наших собственных дополнений в TargetProcess
  • Необходимость наши дополнения доставлять после обновлений (ручных) TargetProcess'а

Наши дополнения – это 3 dll файла, и десяток строк в web.config TargetProcess'а. В принципе, не очень много, но при каждом обновлении TargetProcess удаляет всё из своей bin папки и приводит свой web.config к состоянию “по умолчанию” (сохраняя то, что по его мнению там должно быть, но удаляя все лишние изменения). Соответственно, после каждого обновления нужно взять последние версии сборок и внести нужные строчки в web.config. А так как любому человеку свойственно ошибаться – то обновления периодически проходят не так как ожидалось бы…

Для того, чтобы упростить задачу, я и создал отдельный билд в TeamCity, орый как раз таки и выполняет все рутинные задачи. Таким образом, человеку нужно только обновить приложение на сервере и нажать кнопку Run в TeamCity после завершения обновления. Причина, по которой пришлось делать довольно много шагов в этом направлении – по умолчанию, не дает  MsDeploy скачать *.config файлы. Это такая своеобразная защита от атак, чтобы важные данные, которые находятся в этих файлах, не могли попасть в руки “зловредов”.
Поэтому весь этот блог пост посвящается “костылизации” для автоматизации.

Начинается всё со сборки проекта при помощи Visual Studio (sln) раннера. Это обычный билд, который подчиняется тому, что заложено в csproj файлах проекта – скомпиловать dll файл и положить его в предопределенное место.

Второй шаг: при помощи MsBuild и наших скриптов на целевой сервер доставляются файлы трансформации конфигурации. “Под капотом” скрипта – MsDeploy, который выполняет verb:sync с передаваемыми параметрами исходным и целевым (может быть относительным к вебсайту в IIS, а может быть абсолютными для сервера) путями.

Третий шаг: при помощи MsBuild и наших скриптов на целевом сервере выполняется команда xcopy, которая копирует web.config для последующей трансформации, при помощи файлов, доставленных ранее или для отката, если что-либо пойдет не так. “Под капотом” этого скрипта – также MsDeploy, выполняющий -verb:sync -source:runCommand.

Четвертый шаг, как и третий, копирует web.config на сервере, только в этот раз не из корневого приложения TargetProcess, а из вложенного в него приложения (там конфиг необходим, чтобы удалять мешающие работе хендлеры).

Пятый шаг, используя те же скрипты, что и второй, доставляет собранные в первом шаге DLL файлы в bin папку TargetProcess.

Шестой и седьмой шаги используют скрипт из третьего и четвертого шагов, для того, чтобы запустить Config Transformation Tool на сервере и, при помощи доставленных во втором шаге трансформаций, изменить находящиеся в корневом и Javascript приложениях web.config файлы TargetProcess'а.

Шаг восьмой (он же финальный): при помощи Wget скачивает домашнюю страницу TargetProcess. Если вернется не статус 200, то Wget вернет на выходе не 0 и билд провалится. Если будет статус 200, то вернется 0 и билд будет засчитан как успешный.

Вот такая вот автоматизация.

Естественно, можно было упростить всё это – положить ctt.exe, нужные трансформы и сборки на сервер, и просто не забывать всё это запустить после обновления. Но такой подход не решает другой проблемы: если происходит обновление трансформа или исходников доставляемых dll файлов, то обновлять всё это придется опять таки вручную. Вот и пришлось изобретать вышеописанный велосипед.