argumentos - ¿Cuál es la mejor manera de hacer que TFS envíe cada proyecto a su propio directorio?
msbuild reduce verbosity (11)
Podría tener un buildscript por proyecto, que haría exactamente lo que quiere. Simplemente cree un nuevo archivo TFSBuild, agregue los proyectos que desea construir en el grupo de elementos (en el orden en que los quiere construir), establezca dónde desea que esté la salida. Esto se hace anulando la propiedad - en tu archivo TFSBuild.
Pero también estoy de acuerdo con el póster anterior: ¿por qué no acaba de ejecutar un solo script de compilación y agrega una tarea zip al final? Mantener un script de construcción por proyecto agrega una sobrecarga de mantenimiento ...
Estoy poniendo una gran base de código en Team Foundation Server. Me gustaría que el proceso de compilación creara una construcción "lista para implementar" de nuestros proyectos.
La forma normal en que hemos estado haciendo esto es hacer que la salida de cada proyecto esté en su propia carpeta. Entonces, por ejemplo, terminamos con algo así como
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
Que es la forma en que nos gusta.
TFS, sin embargo, parece querer pegar todo en el mismo directorio.
C:/output/
assembly1.dll
assembly2.dll
assembly3.dll
project1.exe
project1.exe.config
project2.exe
project2.exe.config
project3.exe
project3.exe.config
que, aunque ahorra una cierta cantidad de espacio en disco (los ensamblajes solo están allí una vez) no es como lo queremos.
¿Cuál es la mejor manera de especificar dónde TFS / MSBuild debe poner los archivos de salida? ¿Debo editar archivos sln / csproj de forma individual para lograr esto o puedo hacerlo en el archivo TFSBuild.proj? (es decir, en un archivo específico de MSBuild)
Lo logra anulando la implementación de destino predeterminada de CoreDropBuild.
En su archivo TFSBuild.proj (por defecto almacenado en TeamBuildTypes / <Build Type>) agregue el siguiente objetivo:
<!-- Override default implementation -->
<Target
Name="CoreDropBuild"
Condition=" ''$(SkipDropBuild)''!=''true'' and ''$(IsDesktopBuild)''!=''true'' "
DependsOnTargets="$(CoreDropBuildDependsOn)">
...
</Target>
Dentro de este objetivo puede manipular la salida como lo desee. El valor predeterminado es simplemente copiar todo desde $ (BinariesRoot) / $ (BuildType) a $ (DropLocation) / $ (BuildNumber).
Normalmente utilizo el proyecto Microsoft.Sdc.Tasks para las capacidades de copia de archivos.
Solución simple:
Reemplace todos los nodos <SolutionToBuild> con <SolutionToPublish>. Esto, por supuesto, solo funcionará para proyectos publicables (por ejemplo, proyectos web y aplicaciones), no para proyectos de biblioteca.
Tan sencillo como eso :)
Para cada nodo SolutionToBuild, establezca la propiedad OutDir en $ (OutDir) / SubFolder
Por ejemplo:
<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>
(Esto funciona en TF2008, pero no en TF2005).
Acabo de escribir otro método aquí:
http://mikehadlow.blogspot.com/2009/06/tfs-build-publishedwebsites-for-exe-and.html pero si no puede molestarse en seguir el enlace, aquí está en su totalidad:
En general, es una buena práctica recopilar todo el código bajo el control de su equipo en una solución única de uber, como se describe en este PDF de Patrones y Prácticas, Desarrollo de equipo con la Guía de TFS. Si luego configura el servidor de compilación TFS para construir esta solución, su comportamiento predeterminado es colocar la salida de compilación en una sola carpeta, ''Liberar''.
Cualquier proyecto de aplicación web en su solución también se enviará a una carpeta llamada _PublishedWebsites /. Esto es muy bueno porque significa que simplemente puede robocopy implementar la aplicación web.
Lamentablemente, no existe un comportamiento predeterminado similar para otros tipos de proyectos, como WinForms, consola o biblioteca. Sería muy bueno si pudiéramos tener una carpeta _PublishedApplications / sub con el resultado de cualquier proyecto seleccionado. Afortunadamente no es tan difícil de hacer.
La forma en que _PublishedWebsites funciona es bastante simple. Si miras el archivo de proyecto de tu aplicación web, verás una importación cerca de la parte inferior:
<Import Project="$(MSBuildExtensionsPath)/Microsoft/VisualStudio/v9.0/WebApplications/Microsoft.WebApplication.targets" />
En mi máquina, la propiedad MSBuildExtensionsPath evalúa como C: / Program Files / MSBuild, si abrimos el archivo Microsoft.WebApplication.targets podemos ver que es un archivo MSBuild bastante simple que reconoce cuando la compilación no es una compilación de escritorio, es decir, es una TFS compila y copia el resultado a:
$(OutDir)_PublishedWebsites/$(MSBuildProjectName)
Simplemente copié el archivo Micrsoft.WebApplication.targets, lo puse bajo control de fuente con una ruta relativa desde mis archivos de proyecto y cambié _PublishedWebsites a _PublishedApplications y cambié el nombre del archivo CI.exe.targets. Para cada proyecto que quiero enviar a _PublishedApplications, simplemente agregué esta importación en la parte inferior del archivo del proyecto:
<Import Project="<your relative path>/CI.exe.targets" />
Puede editar CI.exe.targets (o lo que quiera llamar) para hacer su oferta. En mi caso, el único cambio hasta el momento es agregar un par de líneas para copiar el archivo App.config:
<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)/bin" SkipUnchangedFiles="true" />
Hay un montón de cosas en Microsoft.WebApplication.targets que solo son relevantes para las aplicaciones web y pueden ser eliminadas para otros tipos de proyectos, pero lo dejo como ejercicio para el lector.
Por defecto, cada archivo de proyecto (* .csproj, * .vbproj, etc.) especifica un directorio de salida predeterminado (que generalmente es bin / Debug, bin / Release, etc.). Team Build en realidad lo reemplaza para que no esté a merced de las propiedades que el desarrollador establece en el archivo del proyecto, sino también para que Team Build pueda hacer suposiciones sobre dónde se ubican los resultados.
La forma más fácil de anular este comportamiento es establecer CustomizableOutDir en true en el grupo de elementos SolutionToBuild como se muestra aquí:
<ItemGroup>
<SolutionToBuild Include="$(BuildProjectFolderPath)/path/MySolution.sln" />
<Properties>CustomizableOutDir=true</Properties>
</SolutionToBuild>
</ItemGroup>
Esto hará que la estructura de la carpeta desplegable coincida aproximadamente con lo que obtendría localmente si creara la solución.
Este método es definitivamente preferible a anular los objetivos Core * que pueden causar problemas de actualización.
Sling esto en un grupo de propiedades:
<CustomizableOutDir>true</CustomizableOutDir>
Anulará la propiedad global ''CustomizableOutDir'' que, de forma predeterminada, está establecida en False. Establecer esto en las propiedades de SolutionToBuild no funcionará.
Llego un poco tarde a la fiesta respondiendo esta pregunta, pero hay una manera muy simple de implementar la respuesta de Mike Hadlows. Alguien ha escrito un paquete nuget que hace exactamente de lo que Mike habla. Puede encontrarlo aquí: http://www.nuget.org/packages/PublishedApplications
TFS 2012+
Me gusta esta solución ...
Edita tu definición de construcción. En la sección Proceso, configure los MSBuild arguments
para
/p:GenerateProjectSpecificOutputFolder=true
Me gusta esto:
Actualización para TFS 2010 (y próxima TFS 2012). Jason Stangroome ha escrito una buena entrada de blog que describe cómo hacer esto.
http://blog.codeassassin.com/2012/02/03/override-the-tfs-team-build-outdir-property/
(el enlace de arriba está muerto ... vinculándolo a la versión en caché)
Reemplazar la propiedad Build OutDir del equipo TFS
Actualización: con .NET 4.5 hay una manera más fácil .
Una queja muy común de los usuarios del sistema de compilación de Team Foundation Server es que cambia la estructura de carpetas de los resultados del proyecto. De forma predeterminada, Visual Studio coloca todos los archivos en la carpeta respectiva / bin / o / bin // de cada proyecto, pero Team Build solo usa una estructura de carpeta plana colocando todos los archivos en la raíz de la carpeta desplegable o, una vez más, una // subcarpeta en la lista carpeta, con todos los productos del proyecto mezclados.
Además, debido a que Team Build logra esto estableciendo la propiedad OutDir a través de la línea de comandos MSBuild.exe combinada con la prioridad de propiedad de MSBuild, este valor no se puede cambiar fácilmente dentro de MSBuild y la popular solución es editar el archivo Build Process Template * .xaml use un nombre de propiedad diferente . Pero prefiero no tocar el flujo de trabajo a menos que sea absolutamente necesario.
En su lugar, utilizo las funciones Solución previa al objetivo y Tarea en línea de MSBuild v4 para anular la implementación predeterminada de la tarea MSBuild utilizada para construir los proyectos individuales en la solución. En mi implementación alternativa, evito que se pase la propiedad OutDir y paso a través de una propiedad llamada PreferredOutDir en lugar de los proyectos individuales que pueden usarse si así lo desean.
La primera parte, sustituyendo la propiedad OutDir por la propiedad PreferredOutDir en el nivel de solución, se logra simplemente agregando un nuevo archivo al directorio en el que reside su archivo de solución. Este nuevo archivo debe nombrarse siguiendo el patrón "before..sln.targets" , por ejemplo, para un archivo de solución llamado "Foo.sln", el nuevo archivo sería "before.Foo.sln.targets". El contenido de este nuevo archivo debería verse así . Asegúrese de que este nuevo archivo se registre en el control de origen.
La segunda parte, permitir que cada proyecto controle su estructura de carpeta de salida, es simplemente una cuestión de agregar una línea al archivo * .csproj o * .vbproj del proyecto (según el idioma). Ubique el primer elemento dentro del archivo de proyecto que no tiene un atributo de condición especificado y busque la etiqueta de cierre correspondiente para este elemento. Inmediatamente encima de la etiqueta de cierre, agregue una línea como esta:
<OutDir Condition=" ''$(PreferredOutDir)'' != '''' ">$(PreferredOutDir)$(MSBuildProjectName)/</OutDir>
En este ejemplo, el proyecto saldrá a la carpeta desplegable Team Build bajo una subcarpeta llamada igual que el archivo de proyecto (sin la extensión .csproj). Puede elegir un patrón diferente. Además, los proyectos web suelen crear su propia carpeta de salida en una subcarpeta _PublishedWebSites de la carpeta desplegable Team Build, para mantener este comportamiento, simplemente configure la propiedad OutDir para que iguale exactamente a la propiedad PreferredOutDir.
Puede verificar si los cambios han funcionado en su máquina local antes de registrarse simplemente ejecutando MSBuild desde la línea de comandos y especificando la propiedad OutDir como lo hace Team Build, por ejemplo:
msbuild Foo.sln /p:OutDir=c:/TestDropFolder/
Para los curiosos acerca de cómo funciona esto con TFS 2010, esta publicación tiene varias respuestas, de las cuales la vinculada funcionó muy bien para mí.