2010-08-19 7 views
9

저는 MSDeploy를 사용하여 TFS2010의 새로운 빌드 및 배포 기능을 조사했습니다. 지금까지 모든 것이 잘 진행되고 있습니다 (특정 시나리오에 대한 정보를 찾기가 어려웠 음).TFS2010 빌드 정의를 여러 서버에 배포 하시겠습니까?

내 빌드 정의를 수정하여 배포 할 둘 이상의 서버를 지정할 수 있습니까? 내가해야 할 일은 여러 서버에 배포하는 것입니다 (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 - Deploy to Multiple Servers After Build이 문제를 해결하려고하는 유일한 사람인 것처럼 보이지 않습니다.

또한 MSDNe 포럼에 게시 된 IIS.NET 포럼에 게시했습니다 : http://forums.iis.net/t/1170741.aspx. 그것은 많은 견해를 가지고 있었지만, 다시, 대답이 없습니다.

답변

7

두 대의 서버에 배포하기 위해 두 번 프로젝트를 빌드 할 필요는 없습니다. 빌드 프로세스는 일련의 배치 파일을 빌드합니다. 그런 다음 InvokeProcess를 사용하여 여러 서버에 배포 할 수 있습니다.

먼저 ProjectName 변수를 만듭니다. 그런 다음 Assign 활동을 "Compile the Project"순서에 추가하십시오. 이것은 "프로젝트 컴파일 시도"순서에 있습니다. 수동으로 서버에 배포해야하는 경우

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. 

당신이 실행할 수 있습니다 : 여기

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

테스트 서버에 배포 우리 InvokeProcess 활동의 재산입니다 : 여기에 할당의 속성은 빌드 폴더에서 아래의 명령이에

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

내 구현을 다시 할 수있는 기회가 있다면 제대로 된 것 같습니다. 이런 식으로 상자 밖으로 나오지 않는다는 것은 유감입니다. 감사! – Arkiliknam

+0

이제 매개 변수화되도록 프로세스를 업데이트했습니다. MSBuild 인수의 경우 IIS App Path를 지정할 수도 있습니다. 동일한 서버에 여러 인스턴스를 배포해야하는 경우에도 매개 변수화 할 수 있습니다. – 37Stars

0

다른 게시물의 저자입니다. 나는 아직 해결책을 찾지 못했다. 나는 포스트 프로세싱 MSBUILD -sync 작업을 추가하기 위해 워크 플로우를 수정하려고한다고 생각한다. 그것은 가장 우아한 것으로 보이지만 조금 덜 관입하는 것을 찾기를 여전히 희망하고있었습니다.

+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의 Arguments 탭에 MSBuildArguments2이라는 새로운 TFS WorkFlow Argument를 추가했습니다.

alt text

내가 MSBuildArguments의 모든 차례 나오는위한 BuildTemplate 워크 플로우를 통해 검색 (두 차례 나오는이 있었다).

MSBuildArguments을 사용하는 두 작업을 Run MSBuild for Project이라고합니다.

Not String.IsNullOrEmpty(MSBuildArguments2) 

난 후 "실행 프로젝트에 대한 MSBuild에서"작업을 복사하여 새 만일의 "그리고"블록으로 붙여, 업데이트 제목 : 직접이 작업 아래에, 나는 조건을 가진 블록이 "가"새로운 추가 따라서. 새 작업의 ConmmandLineArguments 속성을 업데이트하여 새 인수를 사용해야합니다.

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

는 이러한 수정 후 워크 플로는 다음과 같습니다

alt text

저장 및 새로운 워크 플로우에서 확인하십시오. 이 새 WorkFlow를 사용하도록 빌드 정의를 업데이트 한 다음 빌드 정의의 프로세스 탭에서 사용할 준비가 된 새 인수가 포함 된 Misc라는 새 섹션을 찾을 수 있습니다. 이 새로운 인수를 배포에만 사용하기 때문에 MSBuild Arguments에 사용한 것과 동일한 인수를 복사하고 MSDeployServiceURL을 두 번째 배포 서버로 업데이트했습니다.

alt text

그리고 그입니다. 좀 더 우아한 방법은 MSBuildArguments를 문자열 배열로 변환 한 다음 WorkFlow 프로세스 동안 루프를 반복하는 것입니다. 그러나 이것은 우리의 2 서버 요구 사항에 적합합니다.

희망이 도움이됩니다.

2

내 솔루션은 포장 후 실행되는 새로운 대상이다. 패키지를 생성해야하는 각 프로젝트에는이 대상 파일이 포함되어 있으며 외부에서 설정된 "DoDeployment"속성에 Include 조건을 만들기로 선택했습니다. 또한 각 프로젝트는 대상 서버가 어떤 종류의 프로젝트인지에 따라 적절히 필터링되도록 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 워크 플로에서 작업을 가져 와서 MSBUILD 스크립트로 되돌려 놓습니다. 빌드 후에이 솔루션을 호출하는 솔루션의 모든 프로젝트가 있습니까? 그리고 여기서 나는 MSBUILD가 죽었고 묻혔다 고 생각했다. :) – Arkiliknam

+0

MSBuild 파일을 작성한 후에는 clunky 및 crash-prone WorkFlow 디자이너를 사용하기를 더 좋아했습니다. 패키지를 전개해야하는 각 프로젝트에는 csproj의 대상 파일이 포함되며 대상 호출은 패키지 대상 이후에 자동으로 수행됩니다. –

관련 문제