Sep 23

Sonar: viene … y se va.

 

Hace un tiempo instalé y probé Sonar, una estupenda herramienta que genera un informe muy vistoso y cómo de usar sobre las métricas de nuestro código, Pero al final tuve que abandonarlo. El compilado con maven generando el informe era muy lento y el servidor web de sonar acababa dando timeout por la carga a la que se veía sometido. Al final el compilado con maven fallaba por este timeout y eso me hacía totalmente imposible integrarlo con hudson, para obtener los informes actualizados todas las noches.

El otro día me dio por revisar cómo iba el desarrollo de Sonar, qué nuevas versiones habían sacado, qué problemas habían resuelto … y me resulto interesante que habían corregido/añadido una nueva "feature", la SONAR-764, en la que básicamente dicen que cargan el trabajo en el plugin de sonar para maven en vez de en el servidor web de sonar. Esto tiene pinta de que puede solucionar los problemas de timeout con el servidor de sonar. Así que a ello, descargar, instalar y probar.

Las primeras pruebas manuales funcionan a la perfección. Eso sí, los compilados tardan casi el doble ya que deben generar además todos los reportes de métricas, pero ya no tengo el problema de timeout y el informe acaba correctamente y se publica en el servidor web de sonar.

Siguiente paso, hacer que Hudson genere con sonar ese informe todas las noches y lo publique. Y ahí empezaron los problemas. Algunos proyectos tardaban más en compilar, pero lo hacían todo bien y el informe se publicaba. Pero otros proyectos, no necesariamente los más grandes, acababan dando una excepción en el compilado, indicando que "Sonar no se puede ejecutar" y un NullPointerException en los MOJOS de maven. Tras unas investigaciones rápidas, no llegué a ninguna conclusión ni ningún arreglo. El mismo proyecto compilado manualmente en el sitio donde lo hace hudson funciona, pero si lo hace hudson no funciona.

Así que mi gozo en un pozo. Desinstalar sonar y esperar a una nueva ocasión.

Sep 11

Nodos esclavos en Hudson

 

Ayer, jugando con Hudson, descubrí una característica interesante que podía solucionar algunos de los problemas que teníamos y que además me ha dejado alucinado de la facilidad de instalación. Es la posibilidad de poner a otros ordenadores como esclavos de Hudson, de forma que envíe los compilados de los proyectos a ellos. De esta forma, una sola instalación de Hudson puede disponer de varios ordenadores para hacer los compilados y repartirlos entre ellos según una serie de criterios.

Poner un ordenador esclavo de Hudson en muy sencillo. Desde la misma página web de nuestra instalación de Hudson le damos a "añadir nodo esclavo". Hay varias formas de hacer que Hudson hable con el ordenador esclavo y yo elegí "instalar un servicio hudson-esclavo". Para esta opción, solo hay que dar la IP o nombre del ordenador, un usuario y password con permisos de administrador y luego los detalles "técnicos", como el path del ordenador esclavo donde queremos que hudson trabaje, dónde tiene instalado java o maven, etc. No es necesario que esos paths estén compartidos o sena públcos.

Pues bien, una vez dados estos datos, y esto es lo que me ha alucinado, hudson el sólito copia unos jar en el directorio remoto que le hemos dicho, instala un servicio y lo arranca. A partir de ahí, ya tenemos nuestro ordenador esclavo funcionando para nuestro Hudson.

¿Cómo repartimos nuestros proyectos?. Pues hay varias formas:

  1. Dejar que Hudson reparta como quiera.
  2. Asignar un proyecto (desde su configuración) a un esclavo concreto.
  3. Poner etiquetas a los distintos ordenadores esclavos y luego decir en el proyecto que puede ejecutarse en cualquier ordenador que tenga determinada etiqueta.

Esta última característica está pensada para que las etiquetas sean estilo windowxp, linux, java5, java6, etc en función del sistema operativo o versión de java que tenga instalado. De esta podemos decir que un proyecto debe compilarse en cualquier ordenador esclavo que tenga la etiqueta java5 y que, por supuesto, tendrá instalado java 5.

En nuestra web de hudson, donde habitualmente se ponen las barritas de progreso del compilado, veremos los distintos ordenadores, cada uno con sus barritas correspondiente. Pinchando uno de esos ordenadores, veremos sólo los proyectos asignados a ese ordenador.

La posible pega de todo esto es que los compilados paralelos pueden ser problemáticos, sobre todo si hay proyectos que dependen unos de otros y se compilan a la vez. La versión más moderna de Hudson, la 1.323, permite poner un "check" en la configuración del proyecto, indicándole que se quede en la cola de espera si hay algún proyecto del que depende que esté compilando en ese momento. Ese check tiene un pequeño bug, y es que no se puede salvar, así que hay que marcarlo tocando directamente en el config.xml del proyecto dentro de los directorios de Hudson.

Sep 08

Jueguecitos con Hudson

 

Hace tiempo que usamos Hudson como herramienta de integración continua. Básicamente saca automáticamente todas las noches los fuentes de los proyectos que se han tocado durante el día, los compila y si hay errores de compilado, manda un correo-colleja a los que han tocado el código. Hudson proporciona una interface web, de forma que con nuestro navegador podamos ver en todo momento si los proyectos compilan, qué fallos de compilado tienen, quién ha tocado, qué ha tocado, etc.

Sin embargo, hoy he descubierto que tiene un "jueguecito". A Hudson se le pueden instalar fácilmente plugins, por ejemplo, todos los de métricas (checkstyle, pmd, findbugs, etc), de forma que además de compilar, pasa todas estas métricas y genera unos informes visibles desde el navegador. Pues el jueguecito consiste en un plugin adicional que se puede instalar, el Continuous Integration Game.

Una vez instalado este plugin, debemos activarlo en la configuración de cada proyecto (junto con los informes de métricas). De esta forma, cada vez que compila, Hudson asigna o quita puntos a los desarrolladores que ese día han tocado el código. Les da un punto si compila correctamente, les quita diez si falla, les da puntos si hay test nuevos que pasan, les quita puntos si fallan los test, les da puntos si han corregido métricas, les quita si hay más violaciones de las mismas. Al final, tenemos una tabla de jugadores (desarrolladores) ordenada del de más puntos (el mega-top-developer que lo puede todo) hasta el de menos puntos (el torpe-hasta-decir-basta).

Quizás es injusto para un solo compilado, ya que si falla, se quita diez puntos a todos los que han intervenido, independientemente de que sean o no los causantes. Pero está claro que por estadística, a la larga, el torpe interviene en casi todos los compilados fallidos y el listado de puntos se acabará ordenando de una forma lógica.

Es una chorrada, pero supongo que si hacemos una bromillas con el segundo, el último y animamos al primero a conservar su puesto, puede haber verdaderos piques por hacer el código bien. Pues ahí ha quedado todo instalado, a ver mañana quién es el primero de la lista. Incluso podemos poner que todos los lunes los de la mitad de abajo inviten a café a los de la mitad de arriba o que echen un euro en un bote.

Sep 18

Hudson

 Este comentario de Blaxter me ha llevado a probar las herramientas que él indica para integración continua, en lugar de CruiseControl o Continuum.

La primera herramienta, bitten, la descarté sin probarla, porque parece que es como un plugin para Trac, que de momento no puedo usar, aunque quiero, porque no soporta CVS. Tampoco me fijé demasiado si se puede arrancar suelta, pero me hace la impresión de que sí.

Así que me fuí con la segunda, Hudson.

Una maravilla de herramienta.

La instalación muy sencilla. Se baja uno un .war y ejecuta java -jar hudson.war. Abres el navegador y ya tienes lista la página de hudson, preparada para configurar y añadir proyectos.

La configuración sencilla y toda a vía web. Todavía no he tenido que tocar ningún fichero externo, salvo la variable HUDSON_HOME antes de arrancar, para decirle a Hudson dónde debe situar todo.

Los proyectos se añaden fácil, copiando unos de otros, indicando el repositorio CVS, subversion o lo que sea, si es de maven, de ant, etc.

Sin embargo, lo que más me ha gustado de todo, es que es "inteligente". Trabajando con varios proyectos maven es capaz de ver las dependencias entre proyectos y automáticamente, si un proyecto necesita compilarse, después compila todos los que dependen de él. Y al revés, para mirar si un proyecto necesita compilarse, mira también automáticamente si necesitan compilarse los proyectos de los que depende.

Dicho de otra forma, si tengo un proyecto LIBRERIA y otro proyecto PROYECTO que usa librería, si meto algo en CVS de LIBERIA, me compial LIBRERIA y automáticamente después compila PROYECTO. Y al revés, cuando mira a ver si hay algún cambio de CVS en PROYECTO para ver si necesita compilarlo, mira automáticamente también los posibles cambios en CVS de LIBRERIA.

Esto tiene la ventaja de que garantiza que todos los proyectos están siempre actualizados y compilados con las últimas librerías disponibles de las que dependen y que si se toca una librería, se detecta rápido si eso estropea el compilado de un proyecto.

Sin embargo tiene una "pega" o efecto curioso. Basta tocar un fuente en una librería para que Hudson se ponga a compilar como loco unos proyectos y otros, y los compilados de unos provoquen a su vez los compilados de otros. Por un simpel fuente tocado, puede pasarse un par de horas compilando todas las dependencias y las dependencias de las dependencias (cosa, por otro lado, lógica).

En cuanto al resto, también estupendo. Todo lo que se te ocurre configurar, esta configurable via web (el servidor de email, cuantos logs quieres que guarde, comando para construir los proyectos si no es el de defecto, los path de java, ant, maven, sh, etc, etc, etc. También puedes configurar cuántos hilos de compilado paralelos quieres, de forma que pueden compilar hasta n proyectos simultáneos, eligiendo tú el valor de n.

Me queda pendiente probar bitten, pero de momento Hudson lleva todas las papeletas de quedarse como herramienta.

 

Sep 16

Continuum vs CruiseControl

 Hace tiempo me decidí a instalar en el trabajo una de estas herramientas de integración continua, de esas que todas las noches compilan los proyectos desde cero y mandan correos a los desarrolladores y jefes sobre el éxito o fracaso de esa compilación.

En su momento evalué estas dos: CruiseControl y Continuum. Primero intenté con Continuum, porque parecía ser la más usada junto con Maven, pero me encontré con una pega en ese momento que me requería mucho trabajo para resolverla. Resulta que una vez instalado y todo a través de una interface web, le indicas a Continuum el fichero pom.xml de tu proyecto y él se encarga. La pega gorda, que me hizo desecharlo, es que en proyectos maven que tienen a su vez subproyectos debajo, Continuum obligaba a que el directorio del subproyecto se llamara igual que el artifactId de maven, cosa que en mi caso no era así. A mi me gusta poner los nombres de directorios en mayúsculas y con _ entre palabras, mientras que el artifactId coincide con el nombre del jar, y me gusta más en minúsculas y sin _. Total, que Continuum no me cogía mis proyectos maven complejos compuestos de subproyectos y no me apetecía ponerme a cambiar nombres de directorios o de jars.

La segunda pega de Continuum es que requiere que en el pom.xml esté la información para el sistema de control de versiones (CVS, Subversion, con usuario, nombre de repositorio y proyecto…. y password). Estupendo si es uno solo, pero si hay varios desarrolladores, ¿de quién ponemos ahí la información?. Por supuesto, habría que crear un usuario "anonimo" con acceso de sólo lectura al sistema de control de versiones. Cosa compleja si el servidor es de CVS y además corporativo. Nada menos que una petición al departamente de informática y un "agujero" de seguridad dejando un acceso público a nuestros "super secretos fuentes" (es un decir).

Así que me puse a probar con CruiseControl. Este fue bastante mejor. No tiene casi ningún tipo de configuración a través de interface web, por lo que todo se configura a mano. Tú te haces el checkout, le dices a CruiseControl en un fichero xml dónde están los fuentes, cada cuánto tiene que compilarlos, a quién tiene que enviar correos y listo. La interface web es además mucho más sencilla, un listado de proyectos con un botón de "build" al lado y un enlace para ver los resultados del compilado y poder bajarse los jar.

Así estuvimos funcionando unos años, pero CruiseControl fue presentando sus pegas. El fichero xml de configuración con los proyectos empezó a crecer y crecer, hasta hacerse una pesadilla cualquier modificación (había que tocar en muchos proyectos). Y encima, el botón de "build" le funciona a unos sí y a otros no, con unos navegadores sí y con otros no, y sin una regla fija. A unos les funciona con Internet explores, a otros con firefox, a otros con ninguno. Y otra pega más, a veces, si el código de los test automáticos de JUnit se queda colgado por el motivo que sea, deja colgadas todas las tareas siguientes de compilación de otros proyectos en CruiseControl. No queda más remedio que "matarlo" y volverlo a arrancar.

El otro día decimos bajar y probar una nueva versión de Continuum. Esta vez sí funcionó el importar los pom.xml, puesto que ya admite nombres de directorios y artifactId distintos. La configuración a través de web de todo el sistema es sencilla, aunque si no hace lo que tú quieres, no se puede hacer. Sigue habiendo cosas ocultas en ficheros de configuración ocultos, como la configuración del servidor de correo para que Continuum pueda enviar correos. Y sigue habiendo cosas que no sé si me gustan, como la necesidad del usuario anónimo en CVS y que en el pom.xml deben estar todos los nombres de desarrolladores y correos que intervengan en el proyecto (cosa lógica por un lado, pero que no deja de ser un rollo ponerlo y tenerlo actualizado). En este sentido, CruiseControl usaba el nombre de usuario del commit de cvs para enviarle el correo, o bien hacer un mapeo de ese nombre con una dirección de correo si no coincide.

Pero bueno, ahí tenemos un Continuum instalado y funcionando, hasta ahora bien, y después de un par de meses de prueba quizás (seguro) que nos cargamos el CruiseControl.