Quelle est la meilleure façon d'amener TFS à sortir chaque projet dans son propre répertoire?
je mets une grosse base de données dans le serveur de la fondation de L'équipe. Je voudrais que le processus de construction crée une construction" prête à déployer " de nos projets.
la façon normale que nous avons fait ceci est d'avoir la sortie de chaque projet dans son propre dossier. Ainsi, par exemple, nous nous retrouvons avec quelque chose comme
C:project1
assembly1.dll
assembly2.dll
project1.exe
project1.exe.config
C:project2
assembly2.dll
assembly3.dll
project2.exe
project2.exe.config
C:project3
assembly1.dll
assembly3.dll
project3.exe
project3.exe.config
Qui est la façon dont nous l'aimons.
TFS, cependant, semble vouloir coller tout dans le même répertoire.
C:output
assembly1.dll
assembly2.dll
assembly3.dll
project1.exe
project1.exe.config
project2.exe
project2.exe.config
project3.exe
project3.exe.config
qui, bien qu'il économise une certaine quantité d'espace disque (les assemblages ne sont là qu'une fois chacun) n'est pas ce que nous voulons.
Quelle est la meilleure façon de spécifier où TFS/MSBuild devrait placer les fichiers de sortie? Est-ce que je dois éditer les fichiers sln/csproj individuellement pour réaliser ceci ou Puis-je le faire dans le TFSBuild.dossier proj? (c'est à dire, dans un MSBuild fichier spécifique)
11 réponses
je viens de bloguer une autre méthode ici:
http://mikehadlow.blogspot.com/2009/06/tfs-build-publishedwebsites-for-exe-and.html mais si vous ne pouvez pas prendre la peine de suivre le lien, ici il est en entier:
il est généralement de bonne pratique de recueillir tout le code sous le contrôle de votre équipe dans un uber-solution unique comme décrit dans ce Modèles et pratiques PDF, développement de L'équipe avec TFS Guide. Si vous configurez ensuite l' TFS build server pour construire cette solution, son comportement par défaut est de placer la sortie de compilation dans un seul dossier, ‘Release’.
tous les projets d'application web de votre solution seront également affichés dans un dossier appelé _publishedwebsites\. C'est très bien car cela signifie que vous pouvez simplement robocopy déployer l'application web.
malheureusement, il n'y a pas de comportement par défaut similaire pour les autres types de projets tels que WinForms, console ou bibliothèque. Il ce serait très bien si nous pouvions avoir un répertoire\ sub_applications publié avec les résultats de n'importe quel projet sélectionné. Heureusement, il n'est pas difficile à faire.
la façon dont _publishedwebsites fonctionne est assez simple. Si vous regardez le fichier de projet de votre application web, vous remarquerez une importation près du bas:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
sur ma machine la propriété MSBuildExtensionsPath évalue à C:\Program fichiers\MSBuild, si nous ouvrons le Microsoft.WebApplication.nous pouvons voir que c'est un fichier MSBuild assez simple qui reconnaît quand la construction n'est pas une construction de bureau, c.-à-d. c'est une construction TFS, et copie la sortie à:
$(OutDir)_PublishedWebsites$(MSBuildProjectName)
j'ai simplement copié le Micrsoft.WebApplication.le fichier cible, le mettre sous le contrôle de source avec un chemin relatif à partir de mes fichiers de projet et changé _PublishedWebsites à _PublishedApplications et renommé le fichier CI.EXE.cible. Pour chaque projet que je veux sortir à _applications publiées, j'ai simplement ajouté cette importation au bas du dossier du projet:
<Import Project="<your relative path>\CI.exe.targets" />
vous pouvez éditer CI.EXE.cibles (ou peu importe comment vous voulez l'appeler) pour exécuter vos ordres. Dans mon cas, le seul changement jusqu'à présent est d'ajouter quelques lignes pour copier l'application.fichier de configuration:
<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)\bin" SkipUnchangedFiles="true" />
il y a beaucoup de choses dans Microsoft.WebApplication.des cibles qui ne concernent que les applications web et qui peuvent être supprimées pour d'autres types de projets, mais Je vais laisser ça comme un exercice pour le lecteur.
TFS 2012+
j'aime cette solution...
éditez votre définition de construction. Dans la section Processus, mettre MSBuild arguments
à
/p:GenerateProjectSpecificOutputFolder=true
comme ceci:
par défaut chaque dossier de projet (*.csproj,*.vbproj, etc.) spécifie un répertoire de sortie par défaut (qui est habituellement bin\Debug, bin\Release, etc.). La construction d'équipe l'emporte en fait pour que vous ne soyez pas à la merci de ce que le développeur met dans le dossier de projet, mais aussi pour que la construction D'équipe puisse faire des hypothèses sur l'emplacement des extrants.
la manière la plus simple de contourner ce comportement est de définir CustomizableOutDir à true dans la SolutionToBuild groupe d'articles comme indiqué ici:
<ItemGroup>
<SolutionToBuild Include="$(BuildProjectFolderPath)\path\MySolution.sln" />
<Properties>CustomizableOutDir=true</Properties>
</SolutionToBuild>
</ItemGroup>
cela rendra la structure de dossier de goutte grossièrement correspondre à ce que vous obtiendriez localement si vous construisiez la solution.
cette méthode est certainement préférable à l'annulation des cibles Core* qui peuvent causer des problèmes de mise à niveau.
pour chaque noeud SolutionToBuild, définissez la propriété OutDir à $(OutDir)\SubFolder
Par exemple:
<ItemGroup>
<SolutionToBuild Include="Project1.sln" >
<Properties>OutDir=$(OutDir)\Project1\</Properties>
</SolutionToBuild>
<SolutionToBuild Include="Project2.sln" >
<Properties>OutDir=$(OutDir)\Project2\</Properties>
</SolutionToBuild>
<SolutionToBuild Include="Project3.sln" >
<Properties>OutDir=$(OutDir)\Project3\</Properties>
</SolutionToBuild>
<ItemGroup>
(cela fonctionne dans TF2008, mais pas TF2005.)
je suis un peu en retard à la partie répondant à cette question, mais il ya une façon très simple de mettre en œuvre Mike Hadlow réponse. Quelqu'un a écrit un paquet nuget qui fait exactement ce dont parle Mike. Vous pouvez le trouver ici: http://www.nuget.org/packages/PublishedApplications
mise à Jour pour TFS 2010 (et à venir de TFS 2012). Jason Stangroome a écrit un beau billet de blog décrivant comment faire cela.
http://blog.codeassassin.com/2012/02/03/override-the-tfs-team-build-outdir-property /
(lien ci-dessus mort... lien vers la version en cache)
outrepasser la propriété TFS Team Build OutDir
mise à Jour: .NET 4.5, il est un moyen plus facile de .
une plainte très courante des utilisateurs du serveur de la fondation de L'équipe construire le système est qu'il modifie la structure de dossiers des résultats du projet. Par défaut Visual Studio place tous les fichiers dans le dossier /bin/ ou /bin// de chaque projet, mais Team Build n'utilise qu'une structure de dossier plate mettant tous les fichiers dans la racine du dossier drop ou, encore une fois, un sous-dossier // dans le dossier drop, avec toutes les sorties du projet mélangées ensemble.
de plus parce que Team Build y parvient en définissant la propriété OutDir via le MSBuild.ligne de commande de l'exe combiné avec priorité de propriété de MSBuild cette valeur ne peut pas facilement être changée de L'intérieur de MSBuild elle-même et la solution populaire est à modifier le modèle de processus de construction *.fichier xaml pour utiliser un nom de propriété différent . Mais je préfère ne pas toucher au Workflow à moins que cela ne soit absolument nécessaire.
à la place, j'utilise à la fois la Solution avant cible et les fonctionnalités de tâches en ligne de MSBuild v4 pour outrepasser l'implémentation par défaut de la tâche MSBuild utilisé pour construire les projets individuels dans la solution. Dans mon implémentation alternative, j'empêche la propriété OutDir de passer à travers et je passe à travers une propriété appelée PreferredOutDir à la place que les projets individuels peuvent utiliser si désiré.
la première partie, qui substitue la propriété OutDir à la propriété PreferredOutDir au niveau de la solution, s'obtient simplement en ajoutant un nouveau fichier au répertoire dans lequel se trouve votre fichier solution. Ce nouveau fichier doit être nommé suivant le modèle "avant de..la sln.targets", par exemple pour un fichier solution appelé "Foo.la sln", puis de nouveau le fichier "avant de.Foo.la sln.cible." Le contenu de ce nouveau fichier devrait ressembler à ce . Assurez-vous que ce nouveau fichier est enregistré au contrôle source.
la deuxième partie, qui permet à chaque projet de contrôler la structure de son dossier de sortie, consiste simplement à ajouter une ligne à la *du projet.csproj ou *.fichier vbproj (selon sur la langue). Localisez le premier élément dans le fichier de projet qui n'a pas d'attribut de Condition spécifié, et localisez la balise de fermeture correspondante pour cet élément. Immédiatement au-dessus de l'étiquette de fermeture ajouter une ligne quelque chose comme ceci:
<OutDir Condition=" '$(PreferredOutDir)' != '' ">$(PreferredOutDir)$(MSBuildProjectName)\</OutDir>
dans cet exemple, le projet sortira dans le dossier Team Build drop sous un sous-dossier nommé le même que le dossier de projet (sans le .csproj extension). Vous pouvez choisir un modèle différent. En outre, les projets Web créent généralement leur propre dossier de sortie sous un sous-dossier _PublishedWebSites du dossier Team Build drop, pour maintenir ce comportement il suffit de définir la propriété OutDir pour égaler exactement la propriété PreferredOutDir.
vous pouvez vérifier si vos modifications ont fonctionné sur votre machine locale avant de vous enregistrer simplement en exécutant MSBuild à partir de la ligne de commande et en spécifiant la propriété OutDir comme le fait Team Build, par exemple:
msbuild Foo.sln /p:OutDir=c:\TestDropFolder\
Vous pourriez avoir un buildscript par projet, qui ferait exactement ce que vous voulez. Il suffit de créer un nouveau fichier TFSBuild, d'ajouter les projets que vous voulez avoir construits au groupe item(dans l'ordre où vous les voulez construits), de définir où vous voulez que la sortie soit. Ceci est fait en remplaçant la propriété-dans votre fichier TFSBuild.
mais je suis aussi d'accord avec l'affiche précédente - pourquoi ne pas lancer avec un seul script de construction, et ajouter une tâche zip à la fin? Le maintien d'un buildscript par projet ajoute des frais généraux de maintenance...
Sling cela dans un propertygroup:
<CustomizableOutDir>true</CustomizableOutDir>
il supplantera la propriété 'Customizabloutdir' qui, par défaut, est définie à False. Le paramétrage de ce paramètre dans les propriétés de SolutionToBuild ne fonctionnera pas.
vous y parvenez en supplantant L'implémentation cible CoreDropBuild par défaut.
dans votre TFSBuild.proj file (par défaut stocké sous TeamBuildTypes /
<!-- Override default implementation -->
<Target
Name="CoreDropBuild"
Condition=" '$(SkipDropBuild)'!='true' and '$(IsDesktopBuild)'!='true' "
DependsOnTargets="$(CoreDropBuildDependsOn)">
...
</Target>
dans cette cible, vous pouvez manipuler la sortie comme vous le voulez. Par défaut, il suffit de tout copier de $(BinariesRoot)\$(BuildType) à $(DropLocation)\$(BuildNumber).
j'utilise normalement le Microsoft.La ddc.Les tâches du projet pour la copie de fichier capacités.
Solution Simple:
remplacer tous les noeuds
aussi simple que cela:)