2010-06-18 17 views
7

¿Cuál es la manera indolora/sostenible de usar MSBuild como su corredor de compilación? (Perdonar la longitud de esta publicación)Buenas prácticas: cómo volver a utilizar los archivos .csproj y .sln para crear su secuencia de comandos MSBuild para CI?

Estaba probando suerte en TeamCity (que debo decir que es impresionante la curva de aprendizaje de w.r.t y la funcionalidad lista para usar). Tengo un combo SVN> MSBuild> NUnit> NCover funcionando.

Tenía curiosidad sobre cómo los proyectos moderados a grandes están usando MSBuild - Acabo de señalar MSBuild a mi archivo sln principal. He pasado algún tiempo con NAnt hace algunos años y me pareció que MSBuild es un poco obtuso. Los documentos son demasiado densos/detallados para un principiante.

MSBuild parece tener algo de magia especial para manejar archivos .sln; Intenté escribir a mano una secuencia de comandos de compilación, vinculando/incluyendo archivos .csproj en orden (de modo que pudiera tener tareas de compilación previas a la publicación). Sin embargo, vomitó (citando importaciones objetivo duplicadas). Supongo que la mayoría de los desarrolladores no querrían meterse con los archivos msbuild proj; harían cambios en los archivos .csproj y .sln. ¿Hay alguna herramienta/tarea de MSBuild que realice ingeniería inversa de un nuevo script de un .sln existente + 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 a MSBuild para compilar la solución? Tengo esta sensación persistente de que me estoy perdiendo algo obvio.

Mi objetivo final aquí es tener un script de MSBuild

  • que se basa 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. (por ejemplo, call nunit para ejecutar un proyecto nunit (que parece no ser compatible aún con la interfaz de usuario web de teamcity))
  • se mantiene alejado de los desarrolladores que realizan cambios en la solución. Sin redundancia; no debería exigir a los desarrolladores que realicen el mismo cambio en 2 lugares
+0

¿Mi solución es útil para usted, o está más interesado en algo específico para TeamCity? – Filburt

+0

@Filburt - Lo siento ... se desvió/necesito algo más de tiempo para ponerme manos a la obra con la publicación del blog de Sayed - Creo que lo que estaba buscando era la tarea ''. Fork msbuild desde el script principal. Mi principal necesidad era evitar la duplicación de la configuración de solución/proj en una secuencia de comandos de construcción, pero aún así poder agregar tareas personalizadas de construcción previa/posterior. – Gishu

Respuesta

7

No intenté TeamCity aún, pero instalé un entorno de compilación para nuestro nuevo proyecto de BizTalk.

Siguiendo el excelente consejo de Sayed Ibrahim Hashimi en my own question before starting out, creé un conjunto de scripts de MSBuild .proj y .targets.

El Core

Un script centro .targets de los pasos de generació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 pieza de la base son los objetivos de configuración como te encuentras en tu .csproj archivos

<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 archivo .csproj en sí está representado por un archivo .targets con solo una colección de grupos de elementos 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> 

Juntando todo

El .proj se les va a ejecutar con MSBuild importará su configuración, su proyecto (archivos de código fuente) y el núcleo (Tire, construir y comandos de implementación)

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

    <Import Project="Project.targets"/> 

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

uso de este enfoque pude volver a utilizar las .targets que contienen las fuentes para construir mis unos 50 proyectos en muchas combinaciones diferentes en lugar de crear soluciones de VS para agruparlos.

Espero que esto te sea útil; puedo agregar más detalles si estás interesado.

+0

hola Filburt ¿pueden echar un vistazo a http://stackoverflow.com/questions/34059733/ multiple-hint-paths-in-csproj-file-from-an-text-file-variable – ansar

Cuestiones relacionadas