Я сделал именно это с MSBuild.В моем случае были предприняты следующие шаги:
- TFS выполнила сборку с использованием пользовательского проекта MSBuild, а не файла решения.Будет работать любая система сборки CI, в этом случае ничего особенного в TFS нет.
- В проекте пользовательской сборки, помимо сборки всех проектов, я скопировал кучу файлов "template" web.config в специальныйпапка в папке $ (OutDir).Это закончится падением сборки из TFS.В моем случае встроенные преобразования файла конфигурации были далеко не достаточно сложными, но если это может сработать для вас, то это намного проще.
- Файлы web.config фактически содержали ссылки на другие файлы конфигурации,один для каждой настраиваемой функции.Это использовал пользовательский поставщик конфигурации.Этот метод также будет работать, если у вас только один файл web.config.
- Я включил автоматическое развертывание (публикацию) из командной строки, как новую цель MSBuild в том же настраиваемом проекте MSBuild, который управлялbuild.
- Тогда было легко автоматизировать шаг публикации в основной сборке на виртуальной машине или машине контроля качества, а также сделать возможным ручное развертывание на других серверах (в конечном счете, промежуточных серверах) из командной строки..
Шаблоны web.config имели такие вещи:
In the connection string: "Data Source=${SQLINSTANCE};Initial Catalog=${SQLDATABASENAME}..."
Важно, что разделителями для заменяемых токенов являются $ {}, а не $ (), посколькуMSBuild не будет связываться с фигурными скобками.
На шаге публикации используйте функцию свойства MSBuild для замены битов в файлах конфигурации, из описания MSDN для встроенных задач MSBuild следует следующее:
<UsingTask
TaskName="ReplaceToken"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<File ParameterType="System.String" Required="true" />
<Token ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string content = File.ReadAllText(File);
content = content.Replace(Token, Replacement);
File.WriteAllText(File, content);
]]>
</Code>
</Task>
</UsingTask>
Тогда в вашем проекте вы можете использовать это задание с
<ReplaceToken
File="PathTo\Web.config"
Token="${SQLINSTANCE}"
Replacement=".\SQLEXPRESS"
/>
Это действительно приблизительное руководство, все параметрыs to ReplaceToken также были настроены в метаданных элемента MSBuild, позволяя указать параметры, для которых база данных, сервер, безопасность и т. д. каждая из которых может быть указана индивидуально.
Таким образом, для каждой сборки / развертывания она будет выполнятьсоздавать, копировать шаблоны конфигурации, заменять их на строковые, а затем автоматизировать пакет / публикацию, что является последним этапом.
Лучше всего начать с этого блога: http://vishaljoshi.blogspot.com/2009/02/web-packaging-creating-web-packages.html который объясняет немного, и этот ответ, который содержит лайки к куче других связанных сообщений StackOverflow MsBuild и MsDeploy с несколькими средами , а затем поиск в Интернете с помощью http://www.bing.com/search?q=msbuild+msdeploy+command+line&go=&form=QBLH&qs=n&sk= для более глубокого поиска.Я очень не хочу просто отправить вас в поисковую систему для этой части, но я обнаружил, что существует так много разных сценариев, что трудно выделить один.Около половины ответов в первой десятке имеют представление о некотором ценном ракурсе.Ответ с дополнительной информацией, чтобы помочь сузить мой ответ на данный момент.Для моей реализации я вызвал MSDeploy.exe напрямую из MSBuild, используя задачу Exec.Вот некоторые соображения:
- Как бороться с безопасностью на различных сайтах публикации.Мне приходилось создавать беспорядок в учетных записях службы сборки, и всегда требовалось передавать пароль в командной строке msbuild.Если вы можете обойтись аутентификацией Windows, как вы предполагаете, это будет немного проще.
- Для служб мне пришлось использовать PSExec для запуска installutil на удаленном сервере
- Были некоторые дополнительные настройкиэлементы, которые я автоматизировал с помощью PSExec, вызывающего appcmd на удаленном сервере.
- Легко открыть удаленный общий ресурс на сервере и использовать команду «net use» для сопоставления и отмены сопоставления во время сборки, вы можетеесть другие предпочтения.
- Производительность жесткая.Для больших сайтов он может работать довольно долго, делая это файл за файлом.RoboCopy не быстрее.Я обнаружил, что использование MSDeploy для удаленной упаковки пакетов (указывает на локальное удаление в качестве источника и удаленного общего ресурса для источника пакета) очень быстро для Rackspace.Вам может понадобиться сначала упаковать файл в zip-файл, используя один вызов MSDeploy, а затем отправить пакет удаленно, используя второй.
Надеюсь, это поможет вам начать.Пожалуйста, прокомментируйте или предоставьте более подробную информацию в своем вопросе, если есть что-то, что я действительно пропустил или замутил.
Ответ на комментарий:
Цель "Публикация" - что-то вроде этого,
<Target Name="Publish">
<!-- token replacement in config files, as above -->
<!-- ...lots of custom setup, selection of various properties used below -->
<PropertyGroup>
<_MsDeployExe>$(PROGRAMFILES)\IIS\Microsoft Web Deploy\msdeploy</_MsDeployExe>
<_MsDeploySourceArg>-source:contentpath="$(_BuildDropFolder)"</_MsDeploySourceArg>
<_MsDeployDestArg>-dest:contentpath=\\$(_RemoteComputerName)\DropFolder</_MsDeployDestArg>
</PropertyGroup>
<Message
Text=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
/>
<Exec
Condition="'$(DryRun)' != 'true'"
Command=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
ContinueOnError="false"
WorkingDirectory="$(MSBuildThisFileDirectory)"
/>
</Target>