2010-08-19 4 views
9

Я искал новые функции сборки и развертывания TFS2010 с помощью MSDeploy. Пока все идет хорошо (хотя трудно найти информацию о конкретных сценариях).TFS2010 Определение сборки для развертывания на нескольких серверах?

Могу ли я изменить свое определение сборки, чтобы указать 2 или более серверов для развертывания? Что мне нужно сделать, так это развернуть на несколько серверов (так как у меня два в моей тестовой среде, где используется NLB).

У меня есть определение сборки, которое строит, запускает мои тесты и затем развертывает на ОДИН из моих серверов тестирования (на котором работает MsDeployAgentService). Он отлично работает, и каждый веб-проект развертывается по конфигурации в файле проекта. Аргументы MSBuild я использую:

* /p:DeployOnBuild=True 
* /p:DeployTarget=MsDeployPublish 
* /p:MSDeployServiceURL=http://oawww.testserver1.com.au/MsDeployAgentService 
* /p:CreatePackageOnPublish=True 
* /p:MsDeployPublishMethod=RemoteAgent 
* /p:AllowUntrustedCertificated=True 
* /p:UserName=myusername 
* /p:Password=mypassword 

NB: Я не использую/р: DeployIISAppPath = «XYZ», как оно не развернуть все мои проекты и отменяет свой проект конф.

Могу ли я добавить еще один аргумент построения, чтобы заставить его вызвать более одного MSDeployServiceURL? Как что-то вроде аргумента second/p: MSDeployServiceURL, который указывает другой сервер?

Или мне нужно искать другое решение, такое как редактирование WF?

Я видел почти такой же вопрос, который размещался 2 месяца назад: TFS 2010 - Deploy to Multiple Servers After Build, так что это не похоже, что я единственный, кто пытается это решить.

Я также разместил на форумах IIS.NET, где обсуждается MSDeploy: http://forums.iis.net/t/1170741.aspx. У него было много просмотров, но опять же, ответов нет.

ответ

7

Вам не нужно дважды проектировать проект для развертывания на двух серверах. Процесс сборки будет создавать набор файлов развертывания. Затем вы можете использовать InvokeProcess для развертывания на нескольких серверах.

Сначала создайте переменную с именем ProjectName. Затем добавьте операцию Assign в последовательность «Скомпилировать проект». Это расположено в последовательности «Попробуй скомпилировать проект». Вот свойства Присвоить:

To: ProjectName 
Value: System.IO.Path.GetFileNameWithoutExtension(localProject) 

Вот свойства нашей InvokeProcess деятельности, которая развертывает на тестовом сервере:

Arguments: "/y /M:<server> /u:<domain>\<user> /p:<password>" 
FileName: String.Format("{0}\{1}.deploy.cmd", BuildDetail.DropLocation, ProjectName) 

You will need to change <server>, <domain>, <user>, and <password> to the values that reflect your environment. 

Если вам необходимо вручную развернуть на сервере вы можете запустить из нижеприведенной папки:

deploy.cmd /y /M:<server> /u:<domain>\<user> /p:<password> 
+0

Это похоже на то, что нужно сделать, если у меня будет возможность повторить мою реализацию. Жаль, что это не из-за чего-то вроде этого. Благодаря! – Arkiliknam

+0

Я обновил наш процесс, поэтому теперь они параметризованы. Для аргументов MSBuild вы также можете указать путь приложения IIS. Это также можно параметризовать, если вам нужно развернуть несколько экземпляров на один и тот же сервер. – 37Stars

0

Я являюсь автором другого подобного сообщения. Мне еще предстоит найти решение. Я полагаю, что это будет изменение рабочего процесса, чтобы добавить задачу MSBUILD-обработки постобработки. Кажется, это самый элегантный, но все еще надеялся найти что-то немного менее навязчивое.

+0

Я собирался спуститься по этому пути. Здесь есть запись в блоге: http://blogs.blackmarble.co.uk/blogs/rfennell/archive/2010/08/13/running-msdeploy-to-a-remote-box-from-inside-a-tfs- 2010-build-part-2.aspx, который описывает, как это сделать. Но в конце я добавил второй вызов к MSBUILD и повторно использовал аргументы, которые они предоставляют нам (как подробно описано в моем ответе). – Arkiliknam

6

Я не мог найти решение, которое искал, но вот что я придумал в конце.

Я хотел бы, чтобы решение было простым и настраиваемым в аргументах TFS, в то же время оставаясь в соответствии с уже предоставленным способом MSBuildArguments, который был значительно продвинут. Поэтому я создал новый шаблон сборки и добавил новый аргумент WorkFlow TFS под названием MSBuildArguments2 на вкладке «Аргументы» WorkFlow.

alt text

Я искал через BuildTemplate WorkFlow для всех появлений в MSBuildArguments (там было два мест где).

Две задачи, которые используют MSBuildArguments, называются Run MSBuild for Project. Непосредственно под этой задачей, я добавил новый «Если» блок с условием:

Not String.IsNullOrEmpty(MSBuildArguments2) 

Затем я скопировал «Run MSBuild для проекта» задачу и вставить его в «Тогда» блок нового ИФ, обновляя свое название соответственно. Вам также потребуется обновить свойство ConmmandLineArguments новой задачи, чтобы использовать ваш новый аргумент.

CommandLineArguments = String.Format("/p:SkipInvalidConfigurations=true {0}", MSBuildArguments2)

После этих изменений, то WorkFlow выглядит следующим образом:

alt text

Сохранение и регистрация В новом WorkFlow. Обновите определение сборки, чтобы использовать этот новый WorkFlow, а затем на вкладке «Процесс» в сборке вы найдете новый раздел «Разное» с новым аргументом, готовым к использованию. Поскольку я просто использую этот новый аргумент для развертывания, я скопировал те же самые аргументы, которые я использовал для MSBuild Arguments, и обновил MSDeployServiceURL до моего второго сервера развертывания.

alt text

И вот что. Полагаю, что более элегантный способ состоял бы в том, чтобы преобразовать MSBuildArguments в массив строк, а затем пропустить их во время процесса WorkFlow. Но это соответствует нашим требованиям 2 сервера.

Надеюсь, это поможет!

2

Мое решение для этой цели - это новая цель, которая запускается после пакета. Каждый проект, который должен создать пакет, включает этот файл целей, и я решил сделать условие Include условным для внешнего свойства «DoDeployment». Кроме того, каждый проект определяет свойство DeploymentServerGroup, так что сервер (ы) целевого сервера фильтруется в зависимости от того, какой проект он имеет.

Как вы можете видеть внизу, я просто выполняю командный файл с списком серверов, довольно простой.

<!-- 
This targets file allows a project to deploy its package 

As it is used by all project typesconditionally included from the project file 

->

<UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.BuildStep" AssemblyFile="$(TeamBuildRefPath)\Microsoft.TeamFoundation.Build.ProcessComponents.dll" /> 

<!-- Each Server needs the Group metadatum, either Webservers, Appservers, or Batch. --> 
<Choose> 
    <When Condition="'$(Configuration)' == 'DEV'"> 
     <ItemGroup> 
      <Servers Include="DevWebServer"> 
       <Group>Webservers</Group> 
      </Servers> 
      <Servers Include="DevAppServer"> 
       <Group>Appservers</Group> 
      </Servers> 
     </ItemGroup> 
    </When> 
    <When Condition="'$(Configuration)' == 'QA'"> 
     <ItemGroup> 
      <Servers Include="QAWebServer1"> 
       <Group>Webservers</Group> 
      </Servers> 
      <Servers Include="QAWebServer2"> 
       <Group>Webservers</Group> 
      </Servers> 
      <Servers Include="QAAppServer1"> 
       <Group>Appservers</Group> 
      </Servers> 
      <Servers Include="QAAppServer2"> 
       <Group>Appservers</Group> 
      </Servers> 
     </ItemGroup> 
    </When> 
</Choose> 

<!-- DoDeploy can be set in the build defintion --> 
<Target Name="StartDeployment" AfterTargets="Package"> 

    <PropertyGroup> 
     <!-- The _PublishedWebsites area --> 
     <PackageLocation>$(WebProjectOutputDir)_Package</PackageLocation> 

     <!-- Override for local testing --> 
     <PackageLocation Condition="$(WebProjectOutputDirInsideProject)">$(IntermediateOutputPath)Package\</PackageLocation> 

    </PropertyGroup> 

    <Message Text="Tier servers are @(Servers)" /> 

    <!-- A filtered list of the servers. DeploymentServerGroup is defined in each project that does deployment --> 
    <ItemGroup> 
     <DestinationServers Include="@(Servers)" Condition="'%(Servers.Group)' == '$(DeploymentServerGroup)'" /> 
    </ItemGroup> 

    <Message Text="Dest servers are @(DestinationServers)" /> 

</Target> 

<!-- Only perform the deployment if any servers fit the filters --> 
<Target Name="PerformDeployment" AfterTargets="StartDeployment" Condition="'@(DestinationServers)' != ''"> 

    <Message Text="Deploying $(AssemblyName) to @(DestinationServers)" /> 

    <!-- Fancy build steps so that they better appear in the build explorer --> 
    <BuildStep 
        TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
        BuildUri="$(BuildUri)" 
        Message="Deploying $(AssemblyName) to @(DestinationServers)..."> 
     <Output TaskParameter="Id" PropertyName="StepId" /> 
    </BuildStep> 

    <!-- The deployment command will be run for each item in the DestinationServers collection. --> 
    <Exec Command="$(AssemblyName).deploy.cmd /Y /M:%(DestinationServers.Identity)" WorkingDirectory="$(PackageLocation)" /> 

    <BuildStep 
        TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
        BuildUri="$(BuildUri)" 
        Id="$(StepId)" 
        Status="Succeeded" 
        Message="Deployed $(AssemblyName) to @(DestinationServers)"/> 
    <OnError ExecuteTargets="MarkDeployStepAsFailed" /> 
</Target> 

<Target Name="MarkDeployStepAsFailed"> 
    <BuildStep 
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
      BuildUri="$(BuildUri)" 
      Id="$(StepId)" 
      Status="Failed" /> 
</Target> 

+0

Интересно ... так что вы берете работу из TFS Workflow и помещаете ее обратно в MSBUILD Script. Каждый проект в вашем решении вызывает эту цель после сборки? И здесь я думал, что MSBUILD был мертв и похоронен :) – Arkiliknam

+0

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

Смежные вопросы