¿Cómo puedo conseguir que TFS 2010 construya cada proyecto en un directorio separado?
En nuestro proyecto, nos gustaría que nuestra compilación TFS pusiera 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 aquí, pero ahora que estamos usando compilaciones basadas en flujo de trabajo, esas soluciones no parecen funcionar. La solución que usa la propiedad CustomizableOutDir parecía que funcionaría mejor para nosotros, pero no puedo conseguir que esa propiedad sea reconocida. Personalizé 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 estableciendo en la línea de comandos args a MSBuild. Todavía necesito que se pase OutDir para poder copiar mis archivos a TeamBuildOutDir en el final.
¿Alguna idea de por qué mi parámetro CustomizableOutDir no está siendo reconocido, o si hay una mejor manera de lograr esto?
9 answers
He descubierto una buena manera de hacerlo. Resulta que dado que puede establecer el OutDir a lo que desee dentro del flujo de trabajo, si lo establece en la cadena vacía, MSBuild usará en su lugar la ruta de salida específica 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, establezca sus CommandLineArguments en algo como lo siguiente. Esto le permitirá tenga una referencia al OutDir predeterminado de TFS de su proyecto:
String.Format("/p:CommonOutputPath=""{0}\\""", outputDirectory)
En cada proyecto que desee copiar a la carpeta desplegable, establezca la ruta de salida de la siguiente manera:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath Condition=" '$(CommonOutputPath)'=='' ">bin\Release\</OutputPath>
<OutputPath Condition=" '$(CommonOutputPath)'!='' ">$(CommonOutputPath)YourProjectName\bin\Release\</OutputPath>
</PropertyGroup>
Compruebe todo, y debería tener una compilación en funcionamiento que implemente cada uno de sus proyectos en su propia carpeta debajo de la carpeta desplegable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-06 22:35:18
También resolví este problema, y creo que es más limpio que las soluciones existentes en este hilo.
- Antes de la actividad
Run MSBuild for Project
, agregué una actividadAssign
:projectName = Regex.Replace(New FileInfo(localProject).Name, "\.sln$", "")
. - Luego agregué una actividad
Create Directory
:outputDirectory + "\" + projectName
- Finalmente en la actividad de MSBuild cambié
OutDir
aoutputDirectory + "\" + projectName
.
La plantilla ya rellena localProject
con el nombre de ruta completo 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 extensión, colocando la salida en MySolution
. Necesitarás 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 infiere del nombre del archivo de la solución.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 23:56:14
Tuvimos que hacer esto para evitar el problema donde tenemos una biblioteca Silverlight y.Net con el mismo nombre para la serialización CSLA. La biblioteca sería sobrescrita y nuestras pruebas fallarían.
Usé la respuesta de Jonathan y el post de Jim Lamb, pero descubrí que también necesitas establecer OutDir como vacío.
Por lo tanto, debe hacer estos parámetros para las actividades de MSBuild (si utiliza la siguiente macro, también debe establecer los parámetros de actividad para Clean, de lo contrario obtendrá advertencias que OutputPath no está establecido):
- Establezca CommandLineArguments en
String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, MSBuildArguments)
- Establece OutDir a empty (was BinariesDirectory)
También he creado una macro que puede ejecutar en visual studio que quita el OutputPath de las configuraciones, y añade un PropertyGroup que contiene el OutputPath para todas las configs 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!!!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-29 19:32:54
Los pasos aquí no requieren una modificación del archivo de proyecto - http://lajak.wordpress.com/2011/05/07/customize-binaries-folder-in-tfs-team-build /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-30 17:41:35
Aquí hay una solución muy simple que no requiere ninguna modificación en los archivos de origen o archivos de proyecto. Al configurar su definición de compilación Proceso -> Proyectos a construir, en lugar de especificar su .archivo sln en los proyectos a construir, agregue cada proyecto (.csproj or .vbproj). Ahora, dentro del paso "Ejecutar MSBuild para Project" 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 con el nombre del proyecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-31 20:30:57
He instalado el paquete PublishedApplications de Nuget para cada Ejecutable en Mi Solución y creó subcarpetas en la carpeta _PublishedApplications para cada proyecto durante la compilación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-11 11:25:52
No estoy seguro de si todavía puede conseguir que team build 2010 use la última versión de msbuild, pero hay una nueva propiedad /p:GenerateProjectSpecificOutputFolder=true cuando se especifique, soltará los bits en $(OutDir) \Name(ProjectName)\para cada proyecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-07 02:41:52
No he jugado con conseguir que TFS/MSBuild ponga los archivos de salida en carpetas separadas, por lo que no puedo dar una respuesta directa. Sin embargo, aquí hay un par de sugerencias que no vi en tu enlace:
Puede agregar pasos posteriores a la compilación a los proyectos que copian los archivos requeridos en una estructura de "implementación". (Esto, por supuesto, también se ejecutaría en máquinas de desarrollo, lo que podría ser un dolor). Utilizamos este enfoque para nuestras bibliotecas, que se construyen y luego se copian en una biblioteca compartida carpeta (binarios) para otros proyectos desde los que hacer referencia.
-
Puede agregar un destino de MSBuild para copiar los archivos necesarios donde los desee. Hemos anulado los objetivos predeterminados de "copiar a la carpeta desplegable" para copiar los archivos a otra carpeta, ofuscarlos, firmarlos digitalmente, construirlos en un instalador, firmar digitalmente el instalador y luego copiarlo (y otras cosas útiles como los archivos de mapa de ofuscación) y una lista de cambios desde la última compilación a la carpeta desplegable. En última instancia, agregar su propio objetivo posterior a la compilación le da el máximo control sobre exactamente qué se pone dónde. (En el lado negativo, es posible que tenga que agregar manualmente cualquier dll o EX al destino de copia posterior a la compilación, lo que podría ser una irritación)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-06 21:14:56
Aquí hay otra solución muy simple que no requiere ninguna modificación a los archivos de origen o archivos de proyecto. Al configurar su definición de compilación Proceso -> Proyectos a construir, en lugar de especificar su .archivo sln en los proyectos a construir, agregue cada proyecto (.csproj or .vbproj). Ahora, dentro del paso "Ejecutar MSBuild para Project" de su flujo de trabajo, cambie la propiedad OutDir a lo siguiente:
OutputDirectory + "\" + System.IO.Path.GetFileNameWithoutExtension(serverBuildProjectItem)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-01 16:15:16