Quelle est la meilleure façon de faire en sorte que TFS génère chaque projet dans son propre répertoire?

Je mets un grand code dans Team Foundation Server. Je voudrais que le processus de construction crée une version “prête à déployer” de nos projets.

La façon habituelle de procéder est de faire en sorte que chaque sortie de projet soit dans son propre dossier. Donc, par exemple, on se retrouve 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 que nous l’aimons.

TFS, cependant, semble vouloir tout coller 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 qui, bien que cela é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 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.-à-d. dans un fichier spécifique à MSBuild)

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 être dérangé pour suivre le lien, la voici:

Il est généralement recommandé de collecter tout le code sous le contrôle de votre équipe dans une solution unique, comme décrit dans le PDF Modèles et pratiques, Développement d’équipe avec le Guide 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 bien, car cela signifie que vous pouvez simplement procéder à un déploiement robotique de l’application Web.

Malheureusement, il n’y a pas de comportement par défaut similaire pour d’autres types de projets tels que WinForms, la console ou la 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.

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:

  

Sur ma machine, la propriété MSBuildExtensionsPath est évaluée à C: \ Program Files \ MSBuild, si nous ouvrons le fichier Microsoft.WebApplication.targets, nous pouvons voir que c’est un fichier MSBuild assez simple qui reconnaît que la génération n’est pas une version de bureau. TFS construit et copie la sortie dans:

 $(OutDir)_PublishedWebsites\$(MSBuildProjectName) 

J’ai simplement copié le fichier Micrsoft.WebApplication.targets, l’ai placé sous contrôle de code source avec un chemin d’access relatif à partir de mes fichiers de projet et j’ai modifié _PublishedWebsites en _PublishedApplications et j’ai renommé le fichier CI.exe.targets. Pour chaque projet que je souhaite afficher dans _PublishedApplications, j’ai simplement ajouté cette importation au bas du fichier de projet:

  

Vous pouvez modifier CI.exe.targets (ou tout ce que vous voulez l’appeler) pour faire vos enchères. Dans mon cas, le seul changement jusqu’à présent consiste à append quelques lignes pour copier le fichier App.config:

  

Il y a beaucoup de choses dans Microsoft.WebApplication.targets qui ne concernent que les applications Web et peuvent être supprimées pour d’autres types de projets, mais je vais en laisser un exercice pour le lecteur.

TFS 2012+

J’aime cette solution …

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

/p:GenerateProjectSpecificOutputFolder=true

Comme ça:

entrer la description de l'image ici

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 remplace réellement cela pour que vous ne soyez pas à la fantaisie des propriétés définies par le développeur dans le fichier de projet, mais également pour que Team Build puisse formuler des hypothèses sur l’emplacement des sorties.

La méthode la plus simple pour remplacer ce comportement consiste à définir CustomizableOutDir sur true dans le groupe d’éléments SolutionToBuild, comme illustré ici:

   CustomizableOutDir=true   

Cela fera en sorte que la structure du dossier de repository corresponde approximativement à ce que vous obtiendriez localement si vous construisiez la solution.

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

Pour chaque nœud SolutionToBuild, définissez la propriété OutDir sur $ (OutDir) \ SubFolder
Par exemple:

    OutDir=$(OutDir)\Project1\   OutDir=$(OutDir)\Project2\   OutDir=$(OutDir)\Project3\   

(Cela fonctionne dans TF2008, mais pas dans TF2005.)

Je suis un peu en retard pour la partie qui répond à cette question, mais il existe un moyen très simple d’implémenter la réponse de Mike Hadlows. Quelqu’un a écrit un paquet nuget qui fait exactement ce dont Mike parle. Vous pouvez le trouver ici: http://www.nuget.org/packages/PublishedApplications

Mise à jour pour TFS 2010 (et TFS 2012 à venir). Jason Stangroome a écrit un article sur la façon de le faire.

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-the-tfs-team-build-outdir-property/+&cd=1&hl=fr&ct = clnk & gl = ca

Remplacer 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 se plaignent souvent de modifier la structure des dossiers des résultats du projet. Par défaut, Visual Studio place tous les fichiers dans le dossier respectif / bin / ou / bin // de chaque projet, mais Team Build utilise simplement une structure de dossiers plats pour placer tous les fichiers dans la racine du dossier de repository ou, encore une fois, un sous-dossier // dans la liste déroulante. dossier, avec toutes les sorties du projet mélangées.

En outre, étant donné que Team Build réalise cela en définissant la propriété OutDir via la ligne de commande MSBuild.exe combinée à la priorité de propriété de MSBuild, cette valeur ne peut pas être facilement modifiée depuis MSBuild et la solution populaire consiste à modifier le fichier Build Process Template *. utilisez un nom de propriété différent . Mais je préfère ne pas toucher le workflow à moins que cela ne soit absolument nécessaire.

Au lieu de cela, j’utilise les fonctionnalités Solution Before Target et Inline Task 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 autre implémentation, j’empêche la propriété OutDir d’être transmise et je passe par une propriété appelée PreferredOutDir à la place de ce que les projets individuels peuvent utiliser si vous le souhaitez.

La première partie, substituant 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 votre fichier de solution. Ce nouveau fichier doit être nommé selon 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 archivé dans le contrôle de code source.

La seconde partie, qui permet à chaque projet de contrôler la structure de son dossier de sortie, consiste simplement à append une ligne au fichier * .csproj ou * .vbproj du projet (en fonction de la langue). Recherchez le premier élément dans le fichier de projet qui n’a pas d’atsortingbut Condition spécifié et recherchez la balise de fermeture correspondante pour cet élément. Immédiatement au-dessus de la balise de fermeture, ajoutez une ligne comme ceci:

$(PreferredOutDir)$(MSBuildProjectName)\

Dans cet exemple, le projet sera généré dans le dossier de repository Team Build sous un sous-dossier nommé identique au fichier de projet (sans l’extension .csproj). Vous pourriez 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 repository Team Build. Pour conserver ce comportement, définissez simplement la propriété OutDir afin qu’elle corresponde exactement à la propriété PreferredOutDir.

Vous pouvez vérifier si vos modifications ont bien fonctionné sur votre ordinateur local avant d’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\

Pour ceux qui sont curieux de savoir comment cela fonctionne avec TFS 2010, cet article a plusieurs réponses, dont celle liée a très bien fonctionné pour moi.

Vous pourriez avoir un buildscript par projet, ce qui ferait exactement ce que vous voulez. Créez simplement un nouveau fichier TFSBuild, ajoutez les projets que vous souhaitez créer au groupe d’éléments (dans l’ordre dans lequel vous souhaitez qu’ils soient construits), définissez où vous souhaitez que le résultat soit généré. 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 lancez-vous pas simplement avec un seul script de construction et ajoutez une tâche zip à la fin? Maintenir un buildscript par projet ajoute des frais de maintenance …

Sling this dans un groupe de propriétés:

 true 

Il va remplacer la propriété globale ‘CustomizableOutDir’ qui, par défaut, est définie sur False. Définir cela dans les propriétés de SolutionToBuild ne fonctionnera pas.

Vous y parvenez en remplaçant l’implémentation cible CoreDropBuild par défaut.

Dans votre fichier TFSBuild.proj (stocké par défaut sous TeamBuildTypes / ), ajoutez la cible suivante:

    ...  

Dans cette cible, vous pouvez manipuler la sortie comme vous le voulez. La valeur par défaut est de tout copier de $ (BinariesRoot) \ $ (BuildType) à $ (DropLocation) \ $ (BuildNumber).

J’utilise normalement le projet Microsoft.Sdc.Tasks pour les fonctionnalités de copie de fichiers.

Solution simple:

Remplacez tous les noeuds par . Cela ne fonctionnera bien sûr que pour les projets publiables (projets et applications Web, par exemple), pas pour les projets de bibliothèque.

Aussi simple que cela 🙂