/ / Buenas prácticas: ¿Cómo reutilizar archivos .csproj y .sln para crear su script MSBuild para CI? - .net, msbuild, integración continua

Buenas prácticas: ¿Cómo reutilizar los archivos .csproj y .sln para crear su script de MSBuild para CI? - .net, msbuild, integración continua

¿Cuál es la forma indolora / mantenible de usar MSBuild como su corredor de compilación? (Perdona la duración de esta publicación)

Solo estaba probando suerte en TeamCity (lo que debo decir que es una increíble curva de aprendizaje y una funcionalidad lista para usar). Obtuve un combo SVN> MSBuild> NUnit> NCover funcionando.

Tenía curiosidad sobre cuán moderado a grandelos proyectos están utilizando MSBuild: acabo de señalar MSBuild a mi archivo sln principal. He pasado algún tiempo con NAnt hace algunos años y descubrí que MSBuild es un poco obtuso. Los documentos son demasiado densos / detallados para un principiante.

MSBuild parece tener algo de magia especial paramanejar archivos .sln; Intenté escribir un script de compilación personalizado a mano, vinculando / incluyendo archivos .csproj en orden (de modo que pudiera tener tareas personalizadas de compilación previa y posterior). Sin embargo, vomitó (citando importaciones objetivo duplicadas). Estoy asumiendo la mayoría de los desarrolladores no querrían perder el tiempo con los archivos de proyecto de msbuild; estarían haciendo cambios en los archivos .csproj y .sln. ¿Hay alguna herramienta / tarea de MSBuild que aplique ingeniería inversa a un nuevo script de un archivo .sln + sus archivos .csproj que desconozco?

Si estoy usando MSBuild solo para hacer el paso de compilación, ¿podría usar Nant con una tarea ejecutiva para MSBuild para compilar la solución? Tengo la sensación de que me falta algo obvio.

Mi objetivo final aquí es tener un script de compilación MSBuild

  • que construye la solución
  • que actúa como un script de compilación en lugar de un paso de compilación. Permite tareas pre / post personalizadas. (p. ej., llame a nunit para ejecutar un proyecto de nunit (que parece que aún no se admite a través de la interfaz de usuario web de teamcity))
  • se mantiene fuera del camino de los desarrolladores que realizan cambios en la solución. Sin redundancia; no debería requerir que los desarrolladores realicen el mismo cambio en 2 lugares

Respuestas

7 para la respuesta № 1

Todavía no probé TeamCity pero configuré un entorno de construcción para nuestro nuevo proyecto BizTalk.

Siguiendo los excelentes consejos de Sayed Ibrahim Hashimi en mi propia pregunta antes de comenzar, Creé un conjunto de scripts MSBuild .proj y .targets.

El núcleo

Un script .targets central para los pasos de compilación reales que desea realizar:

<Project DefaultTargets="Deploy" xmlns="...">
<!-- omitted validation steps, see referenced post for details -->
<PropertyGroup>
<PullDependsOn>
$(ValidateDependsOn);
Validate;
</PullDependsOn>
</PropertyGroup>

<PropertyGroup>
<BuildDependsOn>
$(PullDependsOn);
PullFromVersionControl;
</BuildDependsOn>
</PropertyGroup>

<PropertyGroup>
<DeployDependsOn>
$(BuildDependsOn);
Build;
</DeployDependsOn>
</PropertyGroup>

<Target Name="PullFromVersionControl" DependsOnTargets="$(PullDependsOn)">
<Exec Command="..." />
</Target>

<Target Name="Build" DependsOnTargets="$(BuildDependsOn)">
<MSBuild Projects="@(ProjectsToBuild)" />
</Target>

<Target Name="Deploy" DependsOnTargets="$(DeployDependsOn)">
<Exec Command="..." />
</Target>
</Project>

La segunda parte central son los objetivos de configuración como los encuentra en sus archivos .csproj

<Project xmlns="...">
<PropertyGroup Condition=" "$(Environment)" == "DEV" ">
<SomeConfigKey Condition=" "$(SomeConfigKey)" == "" ">Foo</SomeConfigKey>
</PropertyGroup>

<PropertyGroup Condition=" "$(Environment)" == "TEST" ">
<SomeConfigKey Condition=" "$(SomeConfigKey)" == "" ">Bar</SomeConfigKey>
</PropertyGroup>
</Project>

Los proyectos

El único .csproj en sí mismo está representado por un archivo .targets con solo una colección de ItemGroups que necesita para compilar.

<Project xmlns="...">
<ItemGroup>
<!-- this group contains the list of items to pull from version control -->
<Sources Include="@(Sources)" />
<Sources Include="MyProjectRootDir" />
<Sources Include="MyDependentProjectRootDir" />
</ItemGroup>

<ItemGroup>
<ProjectsToBuild Include="@(ProjectsToBuild)" />
<ProjectsToBuild Include="MyProject.csproj" />
</ItemGroup>
</Project>

Poniendo todo junto

El .proj que realmente va a ejecutar con MSBuild importará su configuración, su proyecto (archivos de código fuente) y el núcleo (comandos de extracción, compilación e implementación)

<Project DefaultTargets="Deploy" xmlns="...">
<Import Project="Config.targets"/>

<Import Project="Project.targets"/>

<Import Project="Core.targets"/>
</Project>

Utilizando este enfoque, pude reutilizar los .targets que contienen las fuentes para construir mis 50 proyectos en muchas combinaciones diferentes en lugar de crear soluciones VS para agruparlos.

Espero que le sea útil. Puedo agregar más detalles si está interesado.