Определение сборки TFS2010 для развертывания на несколько серверов?

StackOverflow https://stackoverflow.com/questions/3519501

Вопрос

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

Могу ли я изменить определение своей сборки, чтобы указать 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: Я не использую /P: DeployIisApppath = "xyz", поскольку он не развертывает все мои проекты и переопределяет конфигурацию моего проекта.

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

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

Я видел почти тот же вопрос здесь, опубликованный 2 месяца назад: TFS 2010 - развертывание на нескольких серверах после сборки , так что, похоже, я не единственный, кто пытается решить это.

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

Это было полезно?

Решение

You don't have to build the project twice to deploy to two servers. The build process will build a set of deployment files. You can then use the InvokeProcess to deploy to multiple servers.

First create a variable named ProjectName. Then add an Assign activity to the "Compile the Project" sequence. This is located in the "Try to Compile the Project" sequence. Here are the properties of the Assign:

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

Here are the properties of our InvokeProcess activity that deploys to the test server:

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.

If you need to manually deploy to a server you can run the command below from your build folder:

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

Другие советы

I couldn't find the solution I was looking for, but here's what I came up with in the end.

I wanted to keep the solution simple and configurable within the TFS arguments while at the same time staying in line with the already provided MSBuildArguments method which has been promoted a lot. So I created a new Build Template, and added a new TFS WorkFlow Argument called MSBuildArguments2 in the Arguments tab of the WorkFlow.

alt text

I searched through the BuildTemplate WorkFlow for all occurances of the MSBuildArguments (there were two occurances).

The two tasks that use MSBuildArguments are called Run MSBuild for Project. Directly below this task, I added a new "If" block with the condition:

Not String.IsNullOrEmpty(MSBuildArguments2)

I then copied the "Run MSBuild for Project" task and pasted it into the new If's "Then" block, updating its title accordingly. You'll also need to update the new Task's ConmmandLineArguments property to use your new Argument.

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

After these modifications, the WorkFlow looks like this:

alt text

Save and Check In the new WorkFlow. Update your Build Definition to use this new WorkFlow, then in the build definition's Process tab you will find a new section called Misc with the new argument ready to be used. Because I'm simply using this new argument for deployment, I copied the exact same arguments I used for MSBuild Arguments and updated the MSDeployServiceURL to my second deployment server.

alt text

And that's that. I suppose a more elegant method would be to convert MSBuildArguments into an array of strings and then loop through them during the WorkFlow process. But this suits our 2 server requirements.

Hope this helps!

My solution to this is a new Target that runs after Package. Each project that needs to produce a package includes this targets file, and I chose to make the Include conditional on an externally-set "DoDeployment" property. Additionally each project defines the DeploymentServerGroup property so that the destination server(s) are properly filtered depending on what kind of project it is.

As you can see towards the bottom I'm simply executing the command file with the server list, pretty simple.

<!-- 
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>

I am the author of the other similar post. I have yet to find a solution. I believe it is going to be modifying the workflow to add a postprocessing MSBUILD -sync task. That seems to be the most elegant, but was still hoping to find something a bit less intrusive.

I'm not sure if that could help you with TFS 2010, but I have a blog post for TFS 2012: Multiple web projects deployment from TFS 2012 to NLB enabled environment.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top