Buenas,

después de unos meses en los que he abandonado algunos de mis hobbies, estuve pensando en como aprovechar los mismos en mi trabajo diario y llegué a la conclusión de que necesitaba un

Lanzador de misiles inalámbrico USB disparado por eventos de un servidor Team Foundation Server 2008.

Estar al tanto del resultado de las compilaciones en un servidor TFS es imprescindible para asegurar la calidad del código. Esta información puede llegarnos por varios medios, usualmente por mail; pero mucha gente pasa de esta información por lo que hay que tener otra alternativa para estos casos.

Es por eso que tuve una pequeña idea y he aquí un pequeño diagrama de la misma:

 

  1. Supongamos que Darren (un desarrollador) realiza un CheckIn de código con errores.
  2. La configuración dispara un proceso de Build, en el servidor de compilación.
  3. El Build no puede compilar el código, por lo que se marca como Failed.
  4. Se dispara un evento con el resultado de este Build.
  5. Uno de los subscriptores de los eventos, determina que para este tipo de Build y para el estado Failed, debe informar al servicio de Lanza Misiles de la persona que disparó este Build (Darren)
  6. El servicio de lanzamisiles, obtiene de su configuración la ubicación de Darren y procede a lanzarle un misil.
  7. Darren aprender la lección y verifica el código antes de subirlo.

Muchas personas piensan que un buen equipo de desarrollo funciona en base a la motivación y al respeto. Yo comparto estos pensamientos, pero una vez que patente el TFSBuild Missile Launcher, les propongo utilizarlo y me comentan sus resultados.

Suscripción a eventos de TFS

Volvamos un poco a la tecnología, que es lo trato de escribir mayormente en este blog, y lo primero con lo que tuve que lidiar fue con la suscripción a los eventos de Team Foundation Server 2008.

El sistema de eventos de TFS es un sistema bastante extensible ya que permite varios canales de suscripción y uno de ellos puede ser SOAP, con lo que la suscripción a los eventos se torna en un simple proyecto WCF.

Para esta tarea me basé principalmente en este artículo donde explican paso a paso como crear un proyecto WCF para interpretar eventos TFS. Una vez creado un nuevo proyecto VB.Net de WCF, al que he llamado TfsEventListenerService, lo siguiente ha sido renombrar la interfaz que define los contratos de mi servicio por ITfsEventSuscriber y la clase que los implementa TfsEventSuscriber.

El código de la interfaz y de la clase ha quedado muy simple:

1 ''' <summary> 2 ''' Interface to interact with Team Foundation Server event notificacion service 3 ''' </summary> 4 <ServiceContract(Namespace:="http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")> _ 5 Public Interface ITfsEventSubscriber 6 7 ''' <summary> 8 ''' Notifies the specified event XML. 9 ''' </summary> 10 ''' <param name="eventXml">The event XML.</param> 11 ''' <param name="tfsIdentityXml">The TFS identity XML.</param> 12 <OperationContract(Action:="http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")> _ 13 Sub Notify(ByVal eventXml As String, ByVal tfsIdentityXml As String) 14 15 End Interface 16 17 ''' <summary> 18 ''' Implements a custom event listener for Team Foundation Server events 19 ''' </summary> 20 Public Class TfsEventSubscriber 21 Implements ITfsEventSubscriber 22 23 ''' <summary> 24 ''' Notifies the specified event XML. 25 ''' </summary> 26 ''' <param name="eventXml">The event XML.</param> 27 ''' <param name="tfsIdentityXml">The TFS identity XML.</param> 28 Public Sub Notify(ByVal eventXml As String, ByVal tfsIdentityXml As String) Implements ITfsEventSubscriber.Notify 29 30 ' send information to debug window 31 Dim infoIdentity As String = String.Format("TFS Identity: {0}", tfsIdentityXml) 32 Dim infoEvent As String = String.Format("Event Xml: {0}", eventXml) 33 34 Debug.Print(infoIdentity) 35 Debug.Print(infoEvent) 36 37 ' process tfs event 38 'TfsBuildEventProcessor.BuildEvent.ProcessEvent(eventXml) 39 40 End Sub 41 42 End Class 43

Nota: Es importante remarcar las líneas 37 y 38 que es donde se realiza la interfaz de llamada al proyecto que evalúa el resultado de los builds recibidos por este canal.

Para suscribir este servicio, existe la opción más conocida que es utilizar la herramienta de línea de comandos BISSuscribe, pero en mi caso y como soy un poco más práctico, me he aprovechado de las ventajas del último Service Pack para Microsoft Visual Studio 2008 y he creado la suscripción con los siguientes pasos:

1. En el panel Team Explorer, selecciono la opción Alerts del Team Project sobre el que quiero trabajar.

2. En el formulario Alerts Editor, selecciono New y en el tipo de alerta selecciono Build Alerts

3. En la definición de la nueva alerta defino

 

De esta manera, nuestro servidor TFS informará con un formato SOAP a la url definida cada vez que se realice un build para el proyecto Calculator Build.

Interpretando la información de los Builds de TFS

Una vez creado un servicio WCF que recibirá las notificaciones del servidor TFS, lo siguiente que necesitaba era crear un pequeño intérprete que me permita evaluar el contenido de un build para tomar acciones sobre el mismo. Para esto, cree un nuevo proyecto de librería de clases en C# y dentro del mismo, sobre un XML de un build cree el siguiente schema con su clase asociada. Este es el Xsd con el que interpreto el resultado de los builds.

Adicionalmente en una clase llamada BuildEvent, he creado una función que permite evaluar el resultado de un build.

1 namespace TfsBuildEventProcessor 2 { 3 public class BuildEvent 4 { 5 const string Status_Failed = "Failed"; 6 const string Status_Successfully_Completed = "Successfully Completed"; 7 const string Status_Partially_Succeeded = "Partially Succeeded"; 8 9 /// <summary> 10 /// Processes the event. 11 /// </summary> 12 /// <param name="eventXml">The event XML.</param> 13 public static bool ProcessEvent(string eventXml) 14 { 15 // load xml and deserialize 16 XmlDocument doc = new XmlDocument(); 17 doc.LoadXml(eventXml); 18 BuildCompletionEvent2 bce =(BuildCompletionEvent2) XMLHelper.Deserialize(doc, typeof(BuildCompletionEvent2)); 19 20 // define build status 21 if (bce.CompilationStatus == Status_Successfully_Completed) 22 { 23 // Build sucess, don't do anything 24 Debug.WriteLine("Build Successfully Completed"); 25 } 26 else if (bce.CompilationStatus == Status_Partially_Succeeded) 27 { 28 // Build partially succeeded, don't do anything or maybe yes :D 29 Debug.WriteLine("Build Partially Succeeded"); 30 } 31 else if (bce.CompilationStatus == Status_Failed) 32 { 33 // build failed, find requested by 34 Debug.WriteLine("Build Failed, requested by: {0}", bce.RequestedBy); 35 36 // FIRE TO DEVELOPER !!! 37 } 38 39 // return process result 40 return true; 41 } 42 } 43 }

El código es bastante straighfoward, pero vale la pena remarcar que una vez serializado a un objeto el XML con el resultado del build (línea 16), a continuación realizo una serie de validaciones para conocer el estado del mismo y tomar la acción correspondiente (líneas 21 hasta 35).

Este proyecto es el que servirá de enlace con el lanza misiles USB para indicar que es necesario lanzar un misil a una persona en concreto.

Lansa Misiles Inalámbrico

Hace unos días me llegó por correo, uno de los últimos juguetes al que le tenía ganas desde hace tiempo. Se trata de un lanza misiles inalámbrico USB.

A nivel software el mismo no instala ningún driver, ya que Windows lo reconoce como un dispositivo Human Device Interface (HDI), pero si instala una única aplicación que nos permite controlar el lanza misiles: WirelessLauncher.exe

Esta aplicación nos permite direccionar los misiles utilizando 4 ejes, disparar los mismos, y resetear la posición del lanza misiles a un setup inicial.

La única queja que tengo con la aplicación es que muchas veces no se cierra correctamente y queda una instancia en ejecución. Esto ocasiona que si abrimos nuevas instancias de la aplicación, la misma no puede conectar con el HDI ya que lo “tiene tomado” la instancia que no se ha cerrado correctamente.

 

Conclusión y próximos pasos

En este primer post quería comentar además de la idea general del TFS Build Missile Launcher, las excelentes oportunidades que poseemos para suscribirnos y trabajar con eventos de Team Foundation Server; y un poco sobre la pieza de hardware con la que integraremos el servicio de Builds.

En la 2da parte, comentaré cómo trabajar con este HDI, y como ensamblar todas las partes para lograr tener todo el diagrama en funcionamiento, además de todo el código fuente y un vídeo de ejemplo.

 

Saludos @ Home

El Bruno

 

Referencias

Crossposting from El Bruno