2010-08-19 8 views
9

J'ai examiné les nouvelles fonctionnalités de déploiement et de déploiement de TFS2010 avec MSDeploy. Jusqu'à présent, tout se passe bien (même s'il a été difficile de trouver des informations sur des scénarios spécifiques). Puis-je modifier ma définition de construction pour spécifier 2 serveurs ou plus à déployer? Ce que je dois faire est de déployer sur plusieurs serveurs (comme j'en ai deux dans mon environnement de test qui utilise un NLB). Ce que j'ai maintenant est une définition de construction qui construit, exécute mes tests, puis se déploie sur UN de mes serveurs de test (sur lequel s'exécute MsDeployAgentService). Cela fonctionne correctement et chaque projet Web est déployé comme configuré dans son fichier de projet. comme il ne marche pas déployer tous mes projets et remplace ma config de projet DeployIISAppPath = "xyz": Les arguments que j'utilise MSBuild sont:TFS2010 Build Définition à déployer sur plusieurs serveurs?

* /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: Je ne l'utilise/p. Puis-je ajouter un autre argument de construction pour qu'il appelle plus d'un MSDeployServiceURL? Comme quelque chose comme un argument second/p: MSDeployServiceURL qui spécifie un autre serveur?

Ou dois-je chercher une autre solution, telle que l'édition du WF?

J'ai vu une question presque exacte ici posté il ya 2 mois: TFS 2010 - Deploy to Multiple Servers After Build, donc il ne semble pas que je sois le seul à essayer de résoudre ce problème. J'ai également posté sur les forums IIS.NET où MSDeploy est discuté: http://forums.iis.net/t/1170741.aspx. Il a eu beaucoup de points de vue, mais encore une fois, pas de réponses.

Répondre

7

Vous n'avez pas à générer le projet deux fois pour le déployer sur deux serveurs. Le processus de construction va construire un ensemble de fichiers de déploiement. Vous pouvez ensuite utiliser InvokeProcess pour déployer sur plusieurs serveurs.

Créez d'abord une variable nommée ProjectName. Ajoutez ensuite une activité Attribuer à la séquence "Compiler le projet". Cela se trouve dans la séquence "Essayez de compiler le projet". Voici les propriétés du Assign:

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

Voici les propriétés de notre activité InvokeProcess qui se déploie sur le serveur de test:

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. 

Si vous devez déployer manuellement à un serveur, vous pouvez exécuter le commande ci-dessous à partir de votre dossier de construction:

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

Cela ressemble à la bonne chose à faire si j'ai eu la chance de refaire ma mise en œuvre. C'est juste dommage qu'il ne sorte pas de la boîte avec quelque chose comme ça. Merci! – Arkiliknam

+0

J'ai mis à jour notre processus, ceux-ci sont maintenant paramétrés. Pour les arguments MSBuild, vous pouvez également spécifier le chemin de l'application IIS. Cela peut également être paramétré si vous devez déployer plusieurs instances sur le même serveur. – 37Stars

0

Je suis l'auteur de l'autre article similaire. Je n'ai pas encore trouvé de solution. Je crois qu'il va modifier le flux de travail pour ajouter une tâche MSBUILD -sync de post-traitement. Cela semble être le plus élégant, mais espérait toujours trouver quelque chose d'un peu moins intrusif.

+0

J'allais suivre ce chemin. Il y a une entrée de blog ici: 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 qui couvre comment faire cela. Mais à la fin, j'ai ajouté un deuxième appel à MSBUILD et réutilisé l'idée Arguments qu'ils nous fournissent (comme détaillé dans ma réponse). – Arkiliknam

6

Je ne pouvais pas trouver la solution que je recherchais, mais voici ce que j'ai trouvé à la fin. Je voulais garder la solution simple et configurable dans les arguments TFS tout en restant en ligne avec la méthode déjà fournie MSBuildArguments qui a été beaucoup promue. J'ai donc créé un nouveau modèle de construction et ajouté un nouvel argument TFS WorkFlow appelé MSBuildArguments2 dans l'onglet Arguments de WorkFlow.

alt text

J'ai cherché par la BuildTemplate Dématérialisation occurences du MSBuildArguments (il y avait deux occurences). Les deux tâches qui utilisent MSBuildArguments s'appellent Run MSBuild for Project. Juste en dessous de cette tâche, j'ai ajouté un nouveau « Si » bloc à la condition:

Not String.IsNullOrEmpty(MSBuildArguments2) 

je puis copié la tâche « Exécuter MSBuild pour le projet » et collé dans le nouveau bloc «puis » de Si, de mettre à jour son titre en conséquence. Vous devrez également mettre à jour la propriété ConmmandLineArguments de la nouvelle tâche pour utiliser votre nouvel argument.

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

Après ces modifications, le WorkFlow ressemble à ceci:

alt text

Enregistrer et vérifier dans le nouveau WorkFlow. Mettez à jour votre définition de build pour utiliser ce nouveau WorkFlow, puis dans l'onglet Processus de la définition de construction, vous trouverez une nouvelle section appelée Misc avec le nouvel argument prêt à être utilisé. Comme j'utilise simplement ce nouvel argument pour le déploiement, j'ai copié les mêmes arguments que ceux utilisés pour MSBuild Arguments et mis à jour MSDeployServiceURL vers mon second serveur de déploiement.

alt text

Et c'est ça. Je suppose qu'une méthode plus élégante serait de convertir MSBuildArguments en un tableau de chaînes, puis de les parcourir pendant le processus WorkFlow. Mais cela convient à nos 2 exigences de serveur.

Espérons que cela aide!

2

Ma solution à ceci est une nouvelle cible qui court après le paquet. Chaque projet qui doit produire un paquet inclut ce fichier cible, et j'ai choisi de rendre conditionnel l'inclusion sur une propriété "DoDeployment" définie en externe. De plus, chaque projet définit la propriété DeploymentServerGroup afin que le ou les serveurs de destination soient correctement filtrés en fonction du type de projet.

Comme vous pouvez le voir vers le bas, j'exécute simplement le fichier de commande avec la liste des serveurs, assez 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> 

+0

Intéressant ... vous sortez le travail du flux de travail TFS et le retournez dans un script MSBUILD. Tous les projets de votre solution appellent-ils cette cible après la génération? Et là, je pensais que MSBUILD était mort et enterré :) – Arkiliknam

+0

Une fois que je me suis amélioré à l'écriture de fichiers MSBuild, j'ai commencé à les préférer à l'utilisation du concepteur WorkFlow. Chaque projet qui doit déployer son paquet inclut ce fichier cible depuis son csproj, et l'invocation de la cible est automatique comme c'est le cas après la cible du paquet. –

Questions connexes