sábado, 31 de julio de 2010

Introducción a Builds automáticos o “Cómo corno funciona MSBuild”

En ambientes de desarrollo medianamente profesionales es una práctica muy común contar con Builds automáticos, esto significa que tenemos un mecanismo que por si sólo en algún momento se hace del código fuente de nuestra aplicación, lo compila, corre las pruebas unitarias y publica los resultados. Es una gran idea, por ejemplo, podemos tener configurado para que todas las noches (porque puede ser un proceso muy pesado para hacerlo cuando la gente trabaja) nuestro BuildServer (el servidor donde tenemos configurada toda esta magia) se comunica con el control de código, baja la última versión de todo, compila, corre las pruebas, etc. y nos envía un bonito mail con el resultado.

Básicamente tenemos que poder contar con una herramienta que se encargue de esta automatización, casi que con mucha habilidad podemos hacerlo con el programador de taras de windows y crear tareas que ejecuten los siguientes pasos:

  • Bajen la última versión del código del repositorio
  • Compilen todo en Release
  • Corran las pruebas unitarias
  • Adicionalmente puede verificar otra cosas como Code coverage o políticas de revisión de código, etc.
  • Publique los resultados en un lugar de la red
  • Nos envíen el resultado por mail

La idea detrás de esto

La idea final sería que si trabajamos en un equipo sobre un sistema medianamente complejo asegurarnos que nuestros cambios no rompen cosas que depende de él y viceversa, adicionalmente publique los resultados para que se encuentren disponibles para probarlos, de esta manera todos los días tendríamos la última versión (en desarrollo) lista para ser probada con un nivel de prueba de caja blanca muy bueno (siempre va a depender de nuestras pruebas unitarias) por lo menos sabemos que compila.

Herramientas para Builds automáticos

No, no vamos a usar el programador de tareas, pero no por falta de valor sino porque ya existen herramientas que no sólo permiten programar tareas de este tipo, sino que además traen tareas para:

  • Comunicarse con control de código: TFS, VSS, SVN, Mercurial, etc.
  • Llamar al compilador
  • Correr los test unitarios: MSTest, NUnit, MBUnit, etc.
  • Ejecutar políticas de codecoverage: Visual studio, etc.
  • Enviar Mails.
  • Etc.

Otra cosas muy interesante que estas herramientas suelen traer es la posibilidad de ser disparadas por distintos eventos:

  • En algún momento del día
  • Un día particular de la semana
  • Al hacer check-in del código
  • Al hacer una cantidad de check-ins
  • etc.

Hay varias aplicaciones para hacer esto, entre las más conocidas (por mí al menos) tenemos:

En este post vamos a hablar de MSBuild ya que es el que yo uso y viene con el Visual Studio 2005 en adelante

MSBuild

MSBuild es una aplicación que viene con el framework desde la versión 2.0 y cuando creamos un proyecto en Visual Studio en realidad ese archivos .csprj es un archivo que le dice a MSBuild que compile nuestro proyecto, en resumen, desde Visual Studio 2005 los archivos .csprj son archivos de MSBuild que compilan lo que escribimos en Visual Studio.

Target y Task en MSBuild

Es hora de empezar a jugar con MSBuild, entonces vamos a empezar a jugar con la herramienta para tener claro dos conceptos muy importantes, Targets y Task.

image

Como se ve en el gráfico, un target es un conjunto de tareas, la tareas es el menor unidad de ejecución, sin embargo no podemos ejecutar una tarea que no se encuentre en un target.

Nuestro primer Build

El archivo de configuración para MSBuild más sencillo sería así:

image

Sí, es un XML…..el nodo raíz es del tipo Project y apunto al namespace de Microsoft msbuild del 2003 (en mi caso) dentro tiene que existir al menos un elemento, en nuestro caso un Target con un nombre, en nuestro caso “prueba” y listo, como esto no sirve para nada vamos a agregar una tarea a nuestro Target.

image

Creamos un archivo, por defecto la extensión tiene que ser .target, pero podemos ponerle cualquiera, en mi caso hice un archivo “saludo.xml” y lo dejé en “C:\temp” para ejecutar MSBuild (y casi cualquier herramienta de línea de comandos del framework”) lo mejor es usar la línea de comandos de Visual Studio, que se instala en Tools

image

Llamamos a la línea de comandos y nos ponemos en el path del archivo que acabamos de crear con el código de arriba, la tarea que agregué es una de las tantas que trae MSBuild incorporadas y sirve para mostrar mensajes por consola, entonces escribimos en la consola:

MSBuild saludos.xml

y magia

image

Por supuesto que esto no es muy interesante, pero no olvidemos que se puede llamar al compilador de C#, a MSTest, a cualquier exe, a un bat, a TFS y lo mejor de todo es que podemos crear nuestras propias tareas e invocarlas. Tampoco olvidemos que esto que acabamos de hacer puede ser llamado por TFS como parte de un Build disparado por un check-in.

Tip: podemos tener n Targets y ejecutar lo que querramos indicandole a MSBuild con al argumente /t:nombreTarget

Compilando y ejecutando desde MSBuild

Vamos a crear una pequeña aplicación con C#, compilarla y luego invocarla con MSBuild, el código de la aplicación es éste

image

En el mismo directorio “C:\Temp” cree una clase class.cs con un punto de entrada, que simplemente escribe los parámetros en la consola si los hay, en caso que no los haya escribe “sin elementos” una gran pieza de software si me permiten decirlo, creamos un archivo “compilacion.xml” de este modo:

image

Como vemos la tarea “Csc” invoca al compilador de C# es una tarea predefinida de MSBuild, le decimos que compile class.cs sin más, luego un mensaje y por último la tarea “Exec” permite ejecutar cualquier ejecutable (o un archivo con un ejecutable asociado como un pdf por ejemplo) si todo sale bien deberíamos ver esto:

image

Funcionó, la salida de la aplicación al ser una aplicación de consola va directamente a la línea de comandos de Visual Studio.

Parámetros

Muchas veces necesitamos pasar parámetros a las aplicaciones que invocamos, esto es bien sencillo, las pasamos detrás del nombre del ejecutable, así:

image

image

Perfecto, algo un poco más interesante sería poder pasar parámetro que vengan de otro lado

Propiedades

Otro de los elementos que pueden estar a nivel de Target (es decir ser hijos directos de Project) es “PropertyGroup” elemento dentro del cual podemos definir propiedades, es decir, pares clave-valor que podemos definir a nuestro gusto y utilizarlo dentro del proyecto del MSBuild, por ejemplo:

image

Vemos que hacemos referencia a las propiedades dentro de la tarea Exec haciendo $(nombrePropiedad), como resultado vemos esto:

image

Mágico.

Condiciones

Otra cosa interesante es la posibilidad de que diferentes cosas ocurran a partir de condiciones, por ejemplo

image

En este caso indicamos que si la propiedad Configuration tiene el valor “debug” ejecute la segunda tarea de Csc.

image

Tip: La propiedad Configuration es una propiedad reservada de MSBuild

Ahora sí, algo un poco más real

Ahora vamos a ver un ejemplo más completo de un escenario real, basado en el post de nuestro gran amigo José Romanielo en su blog “Integración Continua en .net y basta de cháchara”

La idea es tener una pequeña configuración que compile nuestro proyecto y ejecute los test. Vamos a hacerlo de a poco.

Tip. Podemos importar proyectos de MSBuild con el tag import, una escenario común es importar tareas comunes que se instalan en nuestra máquina al instalar Visual Studio

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Vamos a crear una librería de clases con una calculadora (tuve un ataque de originalidad) y otro proyecto dentro de la misma solución que compile ambos, corra los test con Nunit y publique los resultados, vamos de a poco.

Presentamos el código de la aplicación:

image

El archivo de configuración para el Build sería el siguiente:

image

En “PropertyGrupo definimos paths de la solución, de salida y donde se encuentra NUnit.

El Target “All” es necesario para invocar a los otros dos, esto lo indicamos en la propiedad “DependsOnTargets” sino MSBuild ejecutaría el primer target y se detendría.

MSBuild task es interesante porque nos permite invocar a una solución y ejecutar todo lo que está dentro, si pensamos un poco nos damos cuenta que la solución invoca csproj que son también archivos de MSBuild!! un detalle piola es la posibilidad de modificar Properties, en este caso modificamos la propiedad OutputPath para que los proyectos envíen el resultado a el directorio que nos interesa.

Ejecutamos y todo funciona según lo esperado.

image

Mágico, faltaría indicar a NUnit que publique los resultados, esto es simplemente pasarle un parámetro adicional, así:

image

Y listo.

Qué nos faltaría?

Como dije al principio es interesante que esto se ejecute automáticamente cuando hacemos check-in o en ciertos momentos del día, si tenemos TFS podemos instalar el TFSBuildAgent que se encarga de hacer esto sino CruiseControl o algo similar.

Otras cosas para ver es dar una vuelta por MSBuild Extension Pack donde hay una gran referencia y muchas tareas comunes, también invetigar un poco .target que vienen por defecto en los archivos csproj.

Saludos, Leonardo.

Referencias

MSBuild References

MSBuild Extension Pack

Cruise Control

3 comentarios:

Edgar dijo...

Muy bueno el ejemplo, practico ante todo, ahora mi duda es estos archivos xml, tengo que crearlos manualmente ?, puedo crearlos con Visual Studio ?

Saludos

Leonardo Micheloni dijo...

Gracias por el comentario Edgar,
Tenés que crearlos manualmente para tener mayor control, si usás TFS con el TeamExplorer se pueden configurar los builds y te genera el archivos (con extensión proj) pero no tenés opciones muy potentes, hay algunas herramientas que lo hacen pero no tengo expericia al respecto.
Saludos, Leonardo.

幸敏薇 dijo...

Currently, there're accepted as a crucial qualification, which often articulates lots around the style of any person and since symbolic connected with the woman good sense connected with vogue. gucci replica Also, having custom made carriers promising with nearly all this wine racks connected with way of living in addition to internet retailers, women of all ages currently don't need to happy with whatever everyday. replica burberry handbags In truth, they will at this point want to opt for custom made purses and handbags intended for unique functions. No matter if you should sign up for some sort of societal gathering or maybe a management and business gathering, louis vuitton replica guarantee that this designer purse you usually are hauling syncs easily with all your garments. fake chanel This convenience of this attire is usually manufactured superior having hugely complimented custom made carriers at unique outlets. Among the finest reasons for having most of these carriers is usually that they may possibly be took having nearly all attires, although undoubtedly a superb fit becomes necessary and so not to ever affect ones synchronization. fake chanel handbags Even so, the vast majority of you will be interested in the prices these purses and handbags for girls. Although even better is of which these carriers are offered on very affordable in addition to marked down premiums by internet retailers.