visual-studio tfs msbuild team-build

visual-studio - jenkins msbuild



Team Build ahora Painfully Slow (4)

Nos encontramos con problemas de rendimiento con nuestra implementación de Team Foundation Build Server y me estoy quedando sin ideas sobre cómo acelerar las cosas. Ya hemos agregado algunos elementos de PropertyGroup para aumentar el rendimiento en varios pasos (SkipClean, SkipLabel, SkipInitializeWorkspace), pero creo que debemos someternos a una importante reestructuración para solucionarlo. Aquí está nuestra configuración:

  • Tenemos alrededor de 40 aplicaciones web que son muy diferentes, pero se ejecutan en un conjunto de conjuntos compartidos
  • Cada una de estas aplicaciones web tiene su propia solución;
  • Hay alrededor de 10 a 25 conjuntos compartidos referenciados por cada una de estas aplicaciones web;
  • Existe una definición de compilación que contiene todas las soluciones que se activan en cada check-in en el trunk;

Y aquí están los problemas básicos con los que nos encontramos

  • Durante la compilación, construirá cada ensamblado compartido tantas veces como se haga referencia a él, en lugar de compilarlo una vez y usarlo para cada aplicación
  • El tiempo de copiado del archivo es bastante lento para el directorio desplegable. Tiene que estar sobre la red compartida y no tomará una ruta local.
  • Cada tantas compilaciones, uno o más de los archivos de salida se "bloquea" y hace que la compilación se rompa incluso si la compilación es correcta.
  • Y otra cosa: también he intentado definiciones de compilación separadas, pero al hacerlo también forzaré que se obtenga otro espacio de trabajo en Obtener la última versión. Prefiero que el servidor de compilación contenga una versión del tronco para construir.

En los últimos meses hemos cedido al letargo e ignorado este problema, pero ahora el tiempo de construcción es de más de una hora a una hora y media.

Estoy jugando con la idea de aprender y cambiar a Cruise Control para tener un mayor control. ¿Alguien está en desacuerdo con eso?

Cualquier ayuda es muy apreciada. ¡Gracias!


En primer lugar, parece que todas sus aplicaciones web están incluidas en el mismo Team Project. Si eso es cierto, divídalos en agrupaciones lógicas. Normalmente, un solo proyecto de equipo debe formar parte de un único modelo de implementación.

En segundo lugar, divida las asambleas compartidas en su propio proyecto de equipo. Una vez movido tiene un par de opciones, puede ramificar el origen o los archivos DLL compilados a los proyectos de equipo que los necesitan. Pueden tener sus propias pruebas de unidad y puede ampliar la creación del equipo para fusionarse automáticamente en una prueba exitosa si así lo desea.

En resumen, necesitas simplificar tu estrategia de construcción.


Hablando de su experiencia personal en la sugerencia de CruiseControl, recuerde que es un "marco" de integración continuo. No resolverá todos sus problemas de forma inmediata (construcciones componentes, activando cada cambio de componente, y compilaciones serializadas, aunque mejorará las cosas). Se necesitará bastante configuración (y tal vez incluso personalización) para obtener las cosas como quieras, así que prepárate para invertir algo de tiempo. Por supuesto, obtendrá un pago masivo a largo plazo si su tiempo de construcción se reduce, si no puede ignorar el problema más, vale la pena invertir algo de tiempo en una mejor solución de CI.

Sin embargo, tenga en cuenta que cualquier esfuerzo de CI es tan bueno como las políticas que tiene implementadas. Tuvimos enormes vacíos de política cuando se trataba de etiquetado de versiones, publicación, dependencias, versiones beta de binarios, compilaciones de archivos ... y muchos otros problemas que ni siquiera consideramos en ese momento.

Además, prepárate para dedicar al menos algunos recursos al mantenimiento de la cosa. No es un trabajo a tiempo completo (y a mí me encanta hacerlo, ya que produce una mejora continua del proceso). Nuestras personalizaciones nos han llevado de una construcción monolítica de 2 horas de nuestro primer producto a más de 400 componentes en 20 productos que se construyen en paralelo en varias máquinas en unos 20 minutos, por lo que vale la pena.


Así que esto es lo que hice, y he reducido la construcción a 9 minutos. Por la cantidad de proyectos que estoy compilando, estoy de acuerdo con eso.

  • Creó una solución que contiene todas las bibliotecas compartidas y todas las webs. Hubo mucho trabajo adicional en este paso porque tuve que arreglar un montón de referencias que eran código heredado o almacenadas en varios lugares.
  • Lo que terminó ahorrando más tiempo fue realizar un movimiento de sistema de archivos en lugar de una copia de red para todos los archivos de salida. Dado que nuestra ubicación de colocación en realidad se encuentra en el servidor de compilación, tiene sentido.

Para realizar el movimiento, simplemente anulo el objetivo CoreDropBuild dentro del archivo TFSBuild.proj:

<Target Name="CoreDropBuild" Condition=" ''$(SkipDropBuild)''!=''true'' and ''$(IsDesktopBuild)''!=''true'' " DependsOnTargets="$(CoreDropBuildDependsOn)" > <Exec Command="move $(BinariesRoot)/Release d:/BuildOutput/$(BuildNumber)/Release"/> </Target>


¿De verdad necesitas construir todo en cada aplicación web? Si los conjuntos compartidos no han cambiado, ¿por qué construirlos una y otra vez?

Aquí hay un pensamiento:

  1. Deje que cada aplicación web tenga su propia carpeta / lib.
  2. Coloque cada ensamblado compartido en la carpeta lib.
  3. Permita que la aplicación web solo haga referencia a conjuntos compartidos desde su carpeta de lib local.
  4. Revisa todo adentro.

Ahora una compilación no debería comenzar a menos que algo haya cambiado, y la compilación no incluirá los ensamblados compartidos.

  • Debería haber una carpeta central que contenga todos los ensamblados compartidos.
  • Cualquier cambio aquí debería propagarse a todas las carpetas locales / lib.
  • Finalmente, cualquier ensamblado compartido debe copiarse en la carpeta central cada vez que cambien.

La idea aquí es tener un proyecto de ensamblaje compartido para conocer solo la carpeta central. Esto simplificará cualquier acción posterior a la construcción necesaria para copiar la construcción.

La carpeta central debe administrarse de tal forma que cualquier cambio se copie en todas las aplicaciones web de referencia.