c# Mejora del tiempo de compilación de CI(.NET)




build continuous-integration (4)

Estamos desarrollando un marco de aplicación + "complementos" utilizando TeamCity como servidor de CI.

detalles del proyecto

  1. 4 soluciones de Visual Studio
  2. ~ 70 proyectos (y en aumento)
  3. Actualmente ejecutando 2 compilaciones usando TeamCity: CI y compilación COMPLETA.

CI - activado en cada compromiso.

COMPLETO - corre todas las noches.

Me gustaría mejorar el rendimiento de ambas compilaciones (especialmente la compilación de CI, ya que debe proporcionar su salida lo más rápido posible).

¿Existen directrices en general sobre qué se puede mejorar de manera efectiva y fácil?

El proceso de compilación simplemente genera un archivo .sln y ejecuta algunas pruebas unitarias.

Direcciones consideradas:

  • MSBuild paralelización
  • Anulando CopyFilesToLocal

No estoy seguro de que estos sean aplicables / resultarán en una ganancia de rendimiento.

Estoy buscando más formas de mejorar el tiempo de construcción (lo que toma alrededor de 3-4 minutos).


Estoy trabajando en más de 500 proyectos de aplicación C #. Los proyectos se compilan en paralelo y copylocal se establece en false. El tiempo de compilación es de aproximadamente 37 minutos sin pruebas unitarias ni cobertura de código. 13min para la construcción incremental sin ningún cambio en el código. Si desactivo la compilación paralela y configuro copylocal en verdadero, el tiempo de compilación es> 1h40min. Tengo una configuración diferente para la compilación local, compilación de check-in cerrada y compilaciones de servidor con la fase de implementación (compilaciones nocturnas).

Aquí están mis experiencias:

  1. Copiar archivos de salida a un directorio no es una buena idea si desea construir sus proyectos en paralelo sin que CopyLocal esté configurado en falso. Mis ensamblajes a veces se bloqueaban cuando varios proyectos hacían referencia al mismo ensamblaje y MSBuild intentaba copiar esta referencia a la carpeta de salida al mismo tiempo. Esta solución fue muy útil para mí. Configuré copylocal en falso para todas las referencias y el tamaño de mi directorio de compilación se redujo 10 veces (10 veces menos I / O). Tengo una configuración diferente para la compilación local y para la compilación del servidor. Configuración diferente para la compilación de check-in cerrada y para la compilación de implementación completa.
  2. Si habilito la compilación paralela, las compilaciones son más rápidas, mucho más rápidas. Si tiene un servidor de compilación sólido, su compilación / m: 2 debería ser 2 veces más rápida que la compilación / m: 1. No tiene nada que ver con las dependencias entre proyectos (si copylocal se establece en falso).
  3. Debería reducir las dependencias entre los proyectos si desea tener una construcción incremental rápida. No tiene ningún impacto en la compilación completa (copylocal false). El tiempo de compilación incremental depende de la ubicación del proyecto modificado en el árbol de compilación.

Sí, MSBuild usa una marca de tiempo de proyectos dependientes para determinar si un proyecto necesita una reconstrucción. Compara los archivos de entrada (archivos de código, conjuntos referenciados, archivos temporales, ..) marca de tiempo con el conjunto de salida. Si algo cambia, tu proyecto es recompilado. Intente reducir el número de depedencias entre proyectos para minimizar la recompilación. Si su cambio fue solo en la parte 'privada' del proyecto, se modificará su conjunto de salida, se modificará la marca de tiempo del conjunto y también se reconstruirán todos los proyectos relacionados. No se puede hacer mucho con esto.

Ejecute su compilación 2 veces con verbosidad de diagnóstico sin ningún cambio en su código y compruebe "Compatibilidad del objetivo de construcción" CoreCompile "completamente" como lo describí here . Puedes tener algo mal en tus archivos de proyecto y tus proyectos se compilan cada vez. Si no cambia nada, su registro de compilación no debe contener los registros "Destino de creación" CoreCompile "completamente".

Nuestro servidor de compilación es una máquina virtual, no una pieza real de hardware. No es una buena idea usar VM para construir servidor, pero no fue mi decisión.

Si tiene varios GB de RAM, intente utilizar parte de ella como un disco duro en memoria. Tu construcción debería ser mucho más rápida :)

Las unidades SSD son sensibles a una alta E / S por día. Tiene un impacto en la garantía.

Espero que ayude a alguien ...;)


Minimiza el trabajo que tu ci construye.

  • configure el área de trabajo con cualquier carpeta innecesaria oculta, para minimizar la cantidad de archivos que necesita obtener del control de código fuente. Si es necesario, reorganice su estructura de origen para que sea fácil eliminar carpetas enteras de datos de la construcción con encubrimiento.

  • asegúrese de que la compilación ci utiliza la obtención incremental y la compilación incremental.

  • solo construye soluciones / proyectos que necesites. Si sus bibliotecas solo se cambian con poca frecuencia, ¿puede precompilarlas y verificar los binarios en el control de código fuente? Si un proyecto no se está desarrollando activamente, no se moleste en construirlo en compilaciones ci.

  • ¿Necesita realizar pruebas unitarias para cada registro? Ejecutamos solo una compilación de código ci simple, con una compilación de prueba separada ejecutándose como ci, pero no más de una vez por hora. Esto reduce el tiempo de construcción de nuestro ci, pero aún así nos permite saber dentro de una hora si rompemos las pruebas unitarias.

  • Del mismo modo, no compile documentación, ofusque, cree instaladores, firme ensamblajes con certificados, etc., y deshabilite cualquier proceso de compilación que copie los resultados en la carpeta desplegable. Las compilaciones de CI están ahí para decirte que si has roto la compilación lo antes posible, no te importa generar salidas binarias útiles.

  • optimice la compilación en general: fusione proyectos, use compilaciones de subprocesos múltiples, use varios agentes de compilación para que las compilaciones ci no tengan que esperar a que se completen otros tipos de compilación. Solo realice las compilaciones completas durante la noche para que su servidor de compilación esté dedicado a ci mientras está trabajando. Mantenga los archivos de origen ordenados (elimine el código no utilizado en lugar de solo comentarlo, elimine los usos / inclusiones no utilizados, etc.)

  • invertir en hardware de servidor mejor construido. Si no tiene una máquina de especificaciones principales, coloque más RAM y un SSD en ella para obtener un impulso de velocidad barato. Asegúrese de que su servidor de compilación esté dedicado a las compilaciones de ci, y no se use para nada más que pueda ralentizarlo. Asegúrese de que la red entre el servidor de compilación y el servidor de servidores sea gigabit. Asegúrese de que no tenga ningún software antivirus en ejecución en el servidor, o al menos que sus exploraciones programadas se ejecuten durante la noche y que sus carpetas de compilación estén en las listas de exclusión de exploración en tiempo real.

  • use tfs check in policy para detener los devs si la compilación de ci ha fallado, para que pueda detener y corregir las roturas de inmediato.


La compilación nocturna es menos susceptible a tiempos de construcción lentos, por lo que debe concentrarse en optimizar las compilaciones activadas por el registro. Nos encontramos con el mismo problema y encontramos lo siguiente para ayudar:

  1. Solo construye lo que has cambiado. Esto significa dividir sus proyectos en otros más pequeños.
  2. Construya la solución en Debug o Release (no en ambos). Deja que la noche se acumule en ambos.
  3. Mantenga las pruebas unitarias pequeñas y rápidas para dar una respuesta rápida de los resultados a los desarrolladores.
  4. Mantenga las tareas no críticas solo para la compilación nocturna (documentación, pruebas de automatización más largas, etc.).
  5. Encadene todas las configuraciones dependientes para que cuando su compilación sea exitosa se compilen con los cambios recientes; Si las configuraciones dependientes fallan, sabrá de inmediato que los cambios no se han integrado con el código existente.

Probamos MSBuild en paralelo, pero no recuerdo si nos ofreció mucho más; Podría ser por los agentes que teníamos.

Además, los tiempos de checkout / checkin tuvieron un gran impacto en el tiempo total, por lo que quizás jugar con el VCS para que solo revise los archivos modificados ayudaría.






teamcity