web-dev-qa-db-fra.com

Quel est le meilleur moyen de faire en sorte que TFS produise chaque projet dans son propre répertoire?

Je mets une base de code volumineuse dans Team Foundation Server. J'aimerais que le processus de construction crée une version "prête à déployer" de nos projets.

La manière habituelle dont nous avons procédé consiste à placer la sortie de chaque projet dans son propre dossier. Ainsi, par exemple, nous finissons 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

C'est comme ça qu'on l'aime.

TFS, cependant, semble vouloir tout mettre 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

ce que nous souhaitons, bien que cela économise une certaine quantité d’espace disque (les assemblys n’y sont présents qu’une seule fois). 

Quelle est la meilleure façon de spécifier où TFS/MSBuild doit placer les fichiers de sortie? Dois-je modifier les fichiers sln/csproj individuellement pour y parvenir ou puis-je le faire dans le fichier TFSBuild.proj? (c'est-à-dire dans un fichier spécifique à MSBuild)

57
Tom Kidd

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 voulez pas être dérangé de suivre le lien, le voici en entier:

En règle générale, il est recommandé de collecter tout le code sous le contrôle de votre équipe dans une seule et même solution, comme décrit dans le document PDF Patterns and Practices, Guide de développement d’équipe avec TFS. Si vous configurez ensuite le serveur de génération TFS pour générer cette solution, son comportement par défaut consiste à placer la sortie de la génération dans un seul dossier, "Release".

Tous les projets d'application Web de votre solution seront également générés dans un dossier nommé _PublishedWebsites \. C’est très agréable, car cela signifie que vous pouvez tout simplement robocopy déployer l’application Web.

Malheureusement, il n’existe pas de comportement similaire par défaut pour les autres types de projets tels que WinForms, console ou bibliothèque. Ce serait très bien si nous pouvions avoir un sous-dossier _PublishedApplications\avec la sortie de tout projet sélectionné. Heureusement, ce n’est pas si difficile à faire.

Le fonctionnement de _PublishedWebsites est assez simple. Si vous consultez le fichier de projet de votre application Web, vous remarquerez une importation vers le bas:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

Sur ma machine, la propriété MSBuildExtensionsPath est évaluée à C:\Program Files\MSBuild. Si nous ouvrons le fichier Microsoft.WebApplication.targets, nous constatons qu’il s’agit d’un fichier assez simple, MSBuild, qui reconnaît que la génération n’est pas une version de bureau, c’est-à-dire TFS build et copie le résultat dans:

$(OutDir)_PublishedWebsites\$(MSBuildProjectName)

J'ai simplement copié le fichier Micrsoft.WebApplication.targets, je l'ai placé sous contrôle de source avec un chemin relatif à partir de mes fichiers de projet et j'ai remplacé _PublishedWebsites par _PublishedApplications et renommé le fichier CI.exe.targets. Pour chaque projet que je veux exporter vers _PublishedApplications, j'ai simplement ajouté cette importation au bas du fichier de projet:

<Import Project="<your relative path>\CI.exe.targets" />

Vous pouvez modifier CI.exe.targets (ou le nom de votre choix) pour répondre à vos demandes. Dans mon cas, la seule modification à ce jour consiste à ajouter quelques lignes pour copier le fichier App.config:

<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)\bin" SkipUnchangedFiles="true" />

Microsoft.WebApplication.targets contient de nombreux éléments qui ne concernent que les applications Web et peuvent être supprimés pour d’autres types de projets, mais je laisserai cela comme exercice pour le lecteur.

44
Mike Hadlow

TFS 2012+

J'aime cette solution ...

Modifiez votre définition de construction. Sous la section Processus, définissez MSBuild arguments sur 

/p:GenerateProjectSpecificOutputFolder=true

Comme ça:

enter image description here

35
Theo

Par défaut, chaque fichier de projet (* .csproj, * .vbproj, etc.) spécifie un répertoire de sortie par défaut (généralement bin\Debug, bin\Release, etc.). Team Build annule en réalité cette action afin de ne pas définir les propriétés définies par le développeur dans le fichier de projet, mais aussi de permettre à Team Build de faire des hypothèses sur l'emplacement des sorties.

Le moyen le plus simple de remplacer ce comportement consiste à définir CustomizableOutDir sur true dans le groupe d'éléments SolutionToBuild, comme indiqué ci-après:

<ItemGroup>
  <SolutionToBuild Include="$(BuildProjectFolderPath)\path\MySolution.sln" />
    <Properties>CustomizableOutDir=true</Properties>
  </SolutionToBuild>
</ItemGroup>

Ainsi, la structure du dossier de dépôt correspond à peu près à ce que vous obtiendrez localement si vous développiez la solution.

Cette méthode est définitivement préférable à la substitution des cibles Core * pouvant entraîner des problèmes de mise à niveau.

10

Pour chaque nœud SolutionToBuild, définissez la propriété OutDir sur $ (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 dans TF2005.)

6
user75810

Je suis un peu en retard pour le parti qui a répondu à cette question, mais il existe un moyen très simple de mettre en œuvre la réponse de Mike Hadlows. Quelqu'un a écrit un paquet de pépites qui fait exactement ce dont parle Mike. Vous pouvez le trouver ici: http://www.nuget.org/packages/PublishedApplications

5
CeejeeB

Mise à jour pour TFS 2010 (et à venir TFS 2012). Jason Stangroome a écrit un article sur le blog de Nice expliquant comment procéder.

http://blog.codeassassin.com/2012/02/03/override-the-tfs-team-build-outdir-property/

(le lien ci-dessus est mort ... lien vers la version en cache)

https://webcache.googleusercontent.com/search?q=cache:4rKu4oB3TwcJ:blog.stangroome.com/2012/02/03/override-sur-tfs-team-build-outdir-property/+&cd = 1 & hl = fr & ct = clnk & gl = ca

Ignorer la propriété TFS Team Build OutDir

Mise à jour: avec .NET 4.5, il existe un moyen plus simple .

Les utilisateurs du système de génération de Team Foundation Server reprochent souvent aux utilisateurs de modifier la structure des dossiers des sorties du projet. Par défaut, Visual Studio place tous les fichiers dans les dossiers/bin/ou/bin // respectifs de chaque projet, mais Team Build utilise simplement une structure de dossier plate pour placer tous les fichiers dans la racine du dossier de dépôt ou, à nouveau, dans un sous-dossier //. dossier, avec toutes les sorties du projet mélangées.

En outre, parce que Team Build y parvient en définissant la propriété OutDir via la ligne de commande MSBuild.exe combinée à priorité de la propriété MSBuild , cette valeur ne peut pas être facilement modifiée à partir de MSBuild lui-même. La solution courante consiste à éditez le fichier * .xaml de modèle de processus de construction pour utiliser un nom de propriété différent . Mais je préfère ne pas toucher le flux de travail à moins que cela ne soit absolument nécessaire.

Au lieu de cela, j'utilise à la fois les fonctionnalités Solution avant la cible et la tâche en ligne de MSBuild v4 pour remplacer l'implémentation par défaut de la tâche MSBuild utilisée pour générer les projets individuels dans la solution. Dans mon implémentation alternative, j'empêche le passage de la propriété OutDir et je passe au travers d'une propriété appelée PreferredOutDir, que les projets individuels peuvent utiliser s'ils le souhaitent.

La première partie, consistant à substituer la propriété OutDir à la propriété PreferredOutDir au niveau de la solution, est obtenue simplement en ajoutant un nouveau fichier au répertoire dans lequel se trouve le fichier de solution. Ce nouveau fichier doit être nommé en suivant le modèle "before..sln.targets". Par exemple, pour un fichier de solution appelé "Foo.sln", le nouveau fichier serait "before.Foo.sln.targets". Le contenu de ce nouveau fichier devrait ressembler à ceci . Assurez-vous que ce nouveau fichier est enregistré dans le contrôle de source.

La deuxième partie, qui permet à chaque projet de contrôler la structure de son dossier de sortie, consiste simplement à ajouter une ligne au fichier * .csproj ou * .vbproj du projet (selon la langue). Localisez le premier élément du fichier de projet pour lequel aucun attribut Condition n’a été spécifié, puis localisez la balise de fermeture correspondante pour cet élément. Immédiatement au-dessus de la balise de fermeture, ajoutez une ligne comme celle-ci:

<OutDir Condition=" '$(PreferredOutDir)' != '' ">$(PreferredOutDir)$(MSBuildProjectName)\</OutDir>

Dans cet exemple, le projet apparaîtra dans le dossier de dépôt de Team Build sous un sous-dossier portant le même nom que le fichier de projet (sans l'extension .csproj). 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 de dépôt Team Build. Pour conserver ce comportement, il suffit de définir la propriété OutDir pour qu'elle corresponde exactement à la propriété PreferredOutDir.

Vous pouvez vérifier si vos modifications ont fonctionné sur votre ordinateur local avant de procéder à l'enregistrement en exécutant simplement MSBuild à partir de la ligne de commande et en spécifiant la propriété OutDir exactement comme le fait Team Build, par exemple:

msbuild Foo.sln /p:OutDir=c:\TestDropFolder\

4
Jeremy Wiebe

Pour ceux qui sont curieux de savoir comment cela fonctionne avec TFS 2010, this post contient plusieurs réponses, dont celle qui a fonctionné me convenait très bien.

1
Case

Vous pourriez avoir un buildscript par projet, qui ferait exactement ce que vous voulez . Créez simplement un nouveau fichier TFSBuild, ajoutez les projets que vous voulez avoir construits dans le groupe d'items veux que la sortie soit. Cela se fait en remplaçant la propriété - dans votre fichier TFSBuild. 

Mais je suis également d'accord avec l'affiche précédente. Pourquoi ne pas simplement exécuter un script de construction et ajouter une tâche Zip à la fin? La maintenance d'un buildscript par projet ajoute des coûts de maintenance ...

0
Erling Paulsen

Sling ceci dans un groupe immobilier:

<CustomizableOutDir>true</CustomizableOutDir>

Elle remplacera la propriété globale 'CustomizableOutDir' qui, par défaut, est définie sur False. Définir ceci dans les propriétés de SolutionToBuild ne fonctionnera pas.

0
user386316