tfs msbuild tfs2010 team-build

¿Cómo puedo obtener TFS 2010 para construir cada proyecto en un directorio separado?



msbuild tfs2010 (9)

En nuestro proyecto, nos gustaría que nuestra compilación TFS coloque cada proyecto en su propia carpeta debajo de la carpeta desplegable, en lugar de colocar todos los archivos en una estructura plana. Para ilustrar, nos gustaría ver algo como esto:

DropFolder/ Foo/ foo.exe Bar/ bar.dll Baz baz.dll

Esta es básicamente la misma pregunta que se hizo here , pero ahora que estamos usando versiones basadas en flujo de trabajo, esas soluciones no parecen funcionar. La solución que utiliza la propiedad CustomizableOutDir parece que funcionaría mejor para nosotros, pero no puedo hacer que esa propiedad sea reconocida. Personalicé nuestro flujo de trabajo para pasarlo a MSBuild como un argumento de línea de comandos (/ p: CustomizableOutDir = true), pero parece que MSBuild simplemente lo ignora y coloca la salida en el OutDir dado por el flujo de trabajo.

Miré los registros de compilación, y puedo ver que las propiedades CustomizableOutDir y OutDir se están configurando en los argumentos de la línea de comandos para MSBuild. Todavía necesito que OutDir se transfiera para poder copiar mis archivos a TeamBuildOutDir al final.

¿Alguna idea de por qué mi parámetro CustomizableOutDir no se reconoce, o si hay una mejor manera de lograrlo?


Aquí hay otra solución muy simple que no requiere modificación de los archivos de origen o de proyecto. Al configurar el Proceso de la definición de compilación -> Proyectos para compilar, en lugar de especificar su archivo .sln en los proyectos para compilar, agregue cada proyecto (.csproj o .vbproj). Ahora dentro del paso "Ejecutar MSBuild para Proyecto" de su flujo de trabajo, cambie la propiedad OutDir a lo siguiente:

OutputDirectory + "/" + System.IO.Path.GetFileNameWithoutExtension(serverBuildProjectItem)


Aquí hay una solución muy simple que no requiere ninguna modificación a los archivos de origen o de proyecto. Al configurar el Proceso de la definición de compilación -> Proyectos para compilar, en lugar de especificar su archivo .sln en los proyectos para compilar, agregue cada proyecto (.csproj o .vbproj). Ahora dentro del paso "Ejecutar MSBuild para Proyecto" de su flujo de trabajo, cambie la propiedad OutDir a lo siguiente:

outputDirectory + "/" + serverBuildProjectItem.Substring(serverBuildProjectItem.LastIndexOf("/"), serverBuildProjectItem.Length - serverBuildProjectItem.LastIndexOf("/")).Replace(".csproj", String.Empty)

Esto colocará la salida de compilación de cada proyecto en un subdirectorio que lleva el nombre del proyecto.


Descubrí una buena manera de hacerlo. Resulta que, dado que puede establecer el OutDir a lo que quiera dentro del flujo de trabajo, si lo establece en la cadena vacía, MSBuild usará el OutputPath específico del proyecto. Eso nos permite ser mucho más flexibles. Aquí está mi solución completa (basada en el flujo de trabajo de compilación predeterminado):

En la tarea Ejecutar MSBuild, establezca OutDir en la cadena vacía. En esa misma tarea, configure sus CommandLineArguments en algo como lo siguiente. Esto le permitirá tener una referencia al OutDir predeterminado de TFS de su proyecto:

String.Format("/p:CommonOutputPath=""{0}//""", outputDirectory)

En cada proyecto que desee copiar en la carpeta desplegable, establezca el OutputPath como:

<PropertyGroup Condition=" ''$(Configuration)|$(Platform)'' == ''Release|AnyCPU'' "> <OutputPath Condition=" ''$(CommonOutputPath)''=='''' ">bin/Release/</OutputPath> <OutputPath Condition=" ''$(CommonOutputPath)''!='''' ">$(CommonOutputPath)YourProjectName/bin/Release/</OutputPath> </PropertyGroup>

Verifique todo y debe tener una compilación que funcione y que implemente cada uno de sus proyectos en su propia carpeta debajo de la carpeta desplegable.


Instalé el paquete PublishedApplications de Nuget para cada ejecutable en My Solution y creé subcarpetas en la carpeta _PublishedApplications para cada proyecto durante la compilación.



No estoy seguro de si todavía puede hacer que Team Build 2010 use la última versión de msbuild, pero hay una nueva propiedad / p: GenerateProjectSpecificOutputFolder = true cuando se especifique, los bits caerán en $ (OutDir) / $ (ProjectName) / para cada proyecto.


No he jugado con obtener TFS / MSBuild para colocar los archivos de salida en carpetas separadas, así que no puedo dar una respuesta directa. Sin embargo, aquí hay un par de sugerencias que no vi en su enlace:

  • Podría agregar pasos posteriores a la compilación a los proyectos que copian los archivos requeridos a una estructura de "implementación". (Esto, por supuesto, también se ejecutaría en las máquinas de desarrollo, lo que podría ser un dolor). Utilizamos este enfoque para nuestras bibliotecas, que se crean y luego se copian en una carpeta de archivos compartidos (binarios) para que otros proyectos puedan consultarlas.

  • Puede agregar un destino de MSBuild para copiar los archivos requeridos donde los desee. Hemos anulado los objetivos predeterminados de "copiar a soltar carpeta" para copiar los archivos a otra carpeta, ofuscarlos, firmarlos digitalmente, crearlos en un instalador, firmar digitalmente el instalador y luego copiarlo (y otras cosas útiles como el archivos de mapa de ofuscación) y una lista de los cambios realizados desde la última compilación a la carpeta desplegable. En última instancia, agregar su propio objetivo posterior a la construcción le brinda el máximo control sobre qué se pone exactamente dónde. (En el lado negativo, es posible que tenga que agregar manualmente cualquier dlls o exes nuevos al objetivo de copia posterior a la compilación, lo que podría ser una irritación)


También resolví este problema y creo que es más limpio que las soluciones existentes en este hilo.

  • Antes de Run MSBuild for Project la actividad Run MSBuild for Project , agregué una actividad Assign : nombre de projectName = Regex.Replace(New FileInfo(localProject).Name, "/.sln$", "") .
  • A continuación, agregué una actividad Create Directory : outputDirectory + "/" + projectName
  • Finalmente en la actividad de MSBuild cambié OutDir a outputDirectory + "/" + projectName .

La plantilla ya llena localProject con el nombre completo de la ruta del archivo .sln que se está construyendo en el Agente, por ejemplo, c:/build/path/to/MySolution.sln . La actividad de asignación corta la ruta y la extensión, colocando la salida en MySolution . Deberá crear la variable projectName e importar System.Text.RegularExpressions y System.IO .

La ventaja sobre la solución de OP es que no tiene que editar cada .csproj , esa información se deduce del nombre del archivo de la solución.


Tuvimos que hacer esto para evitar el problema donde tenemos una biblioteca de Silverlight y .Net con el mismo nombre para la serialización CSLA. La biblioteca se sobrescribiría y nuestras pruebas fallarían.

Utilicé la respuesta de Jonathan y la publicación de Jim Lamb , pero descubrí que también necesitas configurar OutDir para que esté vacío.

Por lo tanto, debe realizar estos parámetros para las actividades de MSBuild (si usa la siguiente Macro, también debe configurar los parámetros de actividad para Limpiar; de lo contrario, recibirá advertencias de que OutputPath no está configurado):

  • Establezca CommandLineArguments en String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, MSBuildArguments)
  • Establecer OutDir en vacío (era BinariesDirectory)

También he creado una macro que se puede ejecutar en Visual Studio que elimina el OutputPath de las configuraciones, y agrega un PropertyGroup que contiene el OutputPath para todas las configuraciones así:

<PropertyGroup Label="OutputPathLabel"> <OutputPath Condition="''$(TeamBuildOutDir)''=='''' ">bin/$(Configuration)/</OutputPath> <OutputPath Condition="''$(TeamBuildOutDir)''!='''' ">$(TeamBuildOutDir)/$(SolutionName)/$(MSBuildProjectName)/$(Configuration)/</OutputPath> </PropertyGroup>

Aquí está la macro:

Public Sub SetTeamBuildOutDir() Dim projectObjects = DTE.Solution.Projects For Each project In projectObjects If project.ProjectItems IsNot Nothing Then SetTeamBuildOutDirRecursive(project) End If Next End Sub Sub SetTeamBuildOutDirRecursive(ByVal proj As Project) If proj.ConfigurationManager Is Nothing Then For Each subProj As ProjectItem In proj.ProjectItems If subProj.SubProject IsNot Nothing Then SetTeamBuildOutDirRecursive(subProj.SubProject) End If Next Else SetTeamBuildOutDir(proj) End If End Sub Sub SetTeamBuildOutDir(ByVal project As Project) ''Do not handle .vdproj If project.FullName.ToLower().EndsWith(".vdproj") Then Exit Sub End If Dim needToSave = False Dim msproject = ProjectRootElement.Open(project.FullName) Dim outputPathGroupExists = False Dim outputPropertyGroup As ProjectPropertyGroupElement = Nothing Dim lastConfigPropertyGroup As ProjectPropertyGroupElement = Nothing For Each propertyGroup In msproject.PropertyGroups If propertyGroup.Label = "OutputPathLabel" Then outputPathGroupExists = True outputPropertyGroup = propertyGroup End If If Not String.IsNullOrEmpty(propertyGroup.Condition) AndAlso _ propertyGroup.Condition.TrimStart().StartsWith("''$(Configuration)") Then lastConfigPropertyGroup = propertyGroup End If ''Remove the OutputPath from the configurations Dim outputPathElement As ProjectPropertyElement = Nothing For Each element As ProjectPropertyElement In propertyGroup.Children If element.Name = "OutputPath" Then outputPathElement = element End If Next If outputPathElement IsNot Nothing Then propertyGroup.RemoveChild(outputPathElement) needToSave = True End If Next ''If we want to always remove the group and add it back (in case of modifications to the group) ''If outputPathGroupExists Then '' msproject.RemoveChild(outputPropertyGroup) '' outputPathGroupExists = False ''End If If Not outputPathGroupExists Then Dim propertyGroup = msproject.CreatePropertyGroupElement() propertyGroup.Label = "OutputPathLabel" ''Need to insert the PropertyGroup before the CSharp targets are included msproject.InsertAfterChild(propertyGroup, lastConfigPropertyGroup) Dim isDbProject = project.FullName.ToLower().EndsWith(".dbproj") Dim outputEmpty = propertyGroup.AddProperty("OutputPath", IIf(Not isDbProject, "bin/$(Configuration)/", "sql/$(Configuration)/")) outputEmpty.Condition = "''$(TeamBuildOutDir)''=='''' " Dim outputTeamBuild = propertyGroup.AddProperty("OutputPath", "$(TeamBuildOutDir)/$(SolutionName)/$(MSBuildProjectName)/$(Configuration)/") outputTeamBuild.Condition = "''$(TeamBuildOutDir)''!='''' " needToSave = True End If If needToSave Then ''checkout the project file with tfs Shell("C:/Program Files/Microsoft Visual Studio 10.0/Common7/IDE/tf.exe checkout " & project.FullName, , True) ''Save the project file msproject.Save() End If End Sub

¡¡¡Espero que esto ayude!!!