Deployment 要部署到多台服务器的TFS2010生成定义?

Deployment 要部署到多台服务器的TFS2010生成定义?,deployment,msbuild,msdeploy,build-definition,Deployment,Msbuild,Msdeploy,Build Definition,我一直在研究使用MSDeploy的TFS2010新构建和部署功能。到目前为止,一切进展顺利(尽管很难找到关于具体场景的信息) 我是否可以修改生成定义以指定要部署到的2台或更多服务器?我需要做的是部署到多个服务器(因为我在使用NLB的测试环境中有两个服务器) 我现在拥有的是一个构建定义,它构建、运行我的测试,然后部署到我的一个测试服务器上(该服务器上运行着MsDeployAgentService)。它工作正常,每个web项目都按照其项目文件中的配置进行部署。我使用的MSBuild参数是: * /p

我一直在研究使用MSDeploy的TFS2010新构建和部署功能。到目前为止,一切进展顺利(尽管很难找到关于具体场景的信息)

我是否可以修改生成定义以指定要部署到的2台或更多服务器?我需要做的是部署到多个服务器(因为我在使用NLB的测试环境中有两个服务器)

我现在拥有的是一个构建定义,它构建、运行我的测试,然后部署到我的一个测试服务器上(该服务器上运行着MsDeployAgentService)。它工作正常,每个web项目都按照其项目文件中的配置进行部署。我使用的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 
注意:我不使用/p:deployiisappath=“xyz”,因为它不会部署我的所有项目并覆盖我的项目配置

我可以添加另一个构建参数以使其调用多个MSDeployServiceURL吗?像第二个/p:MSDeployServiceURL参数那样指定另一台服务器吗

或者我必须寻找其他解决方案,例如编辑WF

两个月前,我在这里看到了一个几乎完全相同的问题:,所以看起来我不是唯一一个试图解决这个问题的人


我还在讨论MSDeploy的IIS.NET论坛上发布了:。这篇文章有很多观点,但同样没有答案。

我是另一篇类似文章的作者。我还没有找到解决办法。我相信它将修改工作流以添加后处理MSBUILD-sync任务。这似乎是最优雅的,但仍然希望找到一些不那么麻烦的解决方案。

我找不到我想要的解决方案,但下面是我最后想到的

我希望在TFS参数中保持解决方案的简单性和可配置性,同时与已提供的
MSBuildArguments
方法保持一致,该方法已被大量推广。因此,我创建了一个新的构建模板,并在工作流的参数选项卡中添加了一个名为
MSBuildArguments2
的新TFS工作流参数

我在BuildTemplate工作流中搜索了
MSBuildArguments
的所有事件(有两个事件)

使用
MSBuildArguments
的两个任务称为
runMSBuildforProject
。在该任务的正下方,我添加了一个新的“If”块,其中包含以下条件:

Not String.IsNullOrEmpty(MSBuildArguments2)
然后,我复制了“Run MSBuild for Project”任务,并将其粘贴到新的If的“then”块中,相应地更新其标题。您还需要更新新任务的ConmmandLineArguments属性以使用新参数

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

经过这些修改后,工作流如下所示:

保存并签入新工作流。更新生成定义以使用此新工作流,然后在生成定义的“流程”选项卡中,您将找到一个名为“Misc”的新部分,其中包含可供使用的新参数。因为我只是在部署中使用这个新参数,所以我复制了用于
MSBuild参数的参数,并将MSDeployServiceURL更新到第二个部署服务器

就这样。我认为更优雅的方法是将MSBuildArguments转换为字符串数组,然后在工作流过程中循环使用它们。但这符合我们的2服务器要求


希望这有帮助

部署到两台服务器不需要构建两次项目。构建过程将构建一组部署文件。然后可以使用InvokeProcess部署到多个服务器

首先创建一个名为ProjectName的变量。然后将分配活动添加到“编译项目”序列中。这位于“尝试编译项目”序列中。以下是分配的属性:

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.
参数:“/y/M:/u:\/p:”
文件名:String.Format(“{0}\{1}.deploy.cmd”,BuildDetail.DropLocation,ProjectName)
您需要将、、和更改为反映您的环境的值。
如果需要手动部署到服务器,可以从生成文件夹运行以下命令:

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

我的解决方案是在包之后运行一个新目标。需要生成包的每个项目都包含这个目标文件,我选择将包含条件设置为外部设置的“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 


网络服务器
应用服务器
网络服务器
网络服务器
应用服务器
应用服务器
$(WebProjectOutputDir)\u包
$(中间输出路径)包\

我不确定这是否能帮助您使用TFS 2010,但我有一篇关于TFS 2012的博文:。

我打算沿着这条路走下去。这里有一篇博文,介绍了如何做到这一点。但最后,我添加了对MSBUILD的第二个调用,并重新使用了它们为我们提供的参数(如我的回答中所述)。如果我有机会重做实现,这看起来是正确的做法。遗憾的是,它没有像这样从盒子里出来。谢谢我已经更新了o
<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>