viernes, diciembre 10, 2004

Configuración básica de CruiseControl

¿Que es la integración continua? Si leemos Automatizar la integración continua: una buena práctica tendremos una muy buena idea de que se trata. ¿Pero como logramos que la teoría se convierta en práctica? Podemos lograrlo instalando una de las herramientas mas conocidas: CruiseControl.

Lo primero es descargarnos la última versión disponible (2.2 al momento de escribir este post), y descompactarla en alguna carpeta que elijamos, por ejemplo c:\work\apps si estamos trabajando con windows.
Luego deberemos crear una carpeta de trabajo para CruiseControl, por ejemplo c:\work\cruise, y dentro de ella tres subdirectrios: checkout para los checkouts del CVS, logs donde CruiseControl creará los reportes y artifacts que nos servirá para contruir elementos que precisan ser mantenidos ente builds.
En la raíz de la carpeta de trabajo (c:\work\cruise), crearemos un fichero config.xml donde especificaremos la configuración de CruiseControl. Por ejemplo:

<cruisecontrol>

<project name="MyProject" buildafterfailed="true">

<bootstrappers>
<currentbuildstatusbootstrapper file="logs/MyProject/status.txt"/>
</bootstrappers>

<modificationset quietperiod="10">
<cvs localworkingcopy="checkout/MyProject"/>
</modificationset>

<schedule interval="60">
<ant antscript="c:\work\apps\apache-ant-1.6.1\bin\ant.bat"
buildfile="build-MyProject.xml" target="build"
uselogger="true" usedebug="false"/>
</schedule>

<log dir="logs/MyProject"/>

<publishers>
<currentbuildstatuspublisher file="logs/MyProject/status.txt"/>
</publishers>
</project>

</cruisecontrol>
En este fichero pondremos un tag <project> para nuestro proyecto, dentro del cual especificaremos (mínimamente):

<bootstrappers> Los bootstrapers son ejecutados antes que el proyecto se contruya, por ejemplo <currentbuildstatusbootstrapper> escribe en el log el estado del build.

<modificationset> Este tag nos permite configurar cómo CruiseControl buscará cambios en el CVS, por ejemplo con el tag <cvs>.

<schedule> Finalmente podemos configurar el script de ant (o Maven) para construir el proyecto, configurando el path a nuestra instalación de ant y el nombre de un fichero a ejecutar con su respectivo target (mas sobre esto adelante).

<log> nos permite especificar donde se crearán las salidas de CruiseControl.

<publishers> Los publishers se ejecutan luego de terminado un build (exitoso o no) y nos permiten, por ejemplo, enviar alertas por email con el resultado del mismo.

Para comenzar el proceso, primero deberemos extraer el proyecto a la carpeta de extracts, por ejemplo con el comando cvs -d :pserver:nombre-de-usuario@nombre-de-servidor-cvs/ checkout -P MyProject. Recordar también que CruiseControl necesita el cvs en el path.
Luego deberemos crear el fichero de configuración de ant c:\work\cruise\build-MyProject.xml que especificamos en el tag <ant>, el cual nos servirá para extraer del CVS la última versión del proyecto y lanzar su propio fichero ant para construir el proyecto:
<project name="build-MyProject" default="build" basedir="checkout/MyProject">

<target name="build">
<!-- Get the latest from CVS -->
<cvs command="-d :pserver:username@cvsservername/ update -P"/>
<!-- Call the target that does everything -->
<ant antfile="build.xml" target="compile"/>
</target>
</project>
Ahora, suponiendo que el build.xml del proyecto (el que utilizamos todos los dias y CruiseControl baja del cvs) tiene un target llamado "compile" que reconstruye el proyecto, tenemos todo listo para poner a CruiseControl a funcionar.
Para ello, estando en el directorio de trabajo, ejecutaremos el .bat (o .sh según el caso) del directorio bin de CruiseControl:

C:\work\cruise>C:\work\apps\cruisecontrol-2.2\main\bin\cruisecontrol.bat
[cc]dic-10 08:01:15 Main - CruiseControl Version 2.2
[cc]dic-10 08:01:16 trolController- projectName = [MyProject]
[cc]dic-10 08:01:16 Project - Project MyProject: reading settings from config file [C:\work\cruise\config.xml]
[cc]dic-10 08:01:16 Project - Project MyProject starting
[cc]dic-10 08:01:16 Project - Project MyProject: idle
[cc]dic-10 08:01:16 BuildQueue - BuildQueue started
[cc]dic-10 08:01:16 Project - Project MyProject started
[cc]dic-10 08:01:16 Project - Project MyProject: next build in 1 minutes
[cc]dic-10 08:01:16 Project - Project MyProject: waiting for next time to build


Para ver como van progresando los builds, nada mejor que la aplicación web que viene con CruiseControl. Necesitaremos instalarla copiando c:\work\apps\cruisecontrol-2.2\reporting\jsp\dist\cruisecontrol.war a la carpeta webapps de Tomcat (o del servidor que creamos conveniente) y dejando que se despliegue. Pero también deberemos modificar el fichero web.xml de la aplicación para que apunte a nuestros directorios de trabajo. Mas específicamente, el <context-param> "logDir" y el "rootDir" del servlet ArtifactServlet deben apuntar a c:\work\cruise\logs.
Luego accederemos a la aplicación mediante al url http://localhost:8080/cruisecontrol, cambiando localhost y 8080 al nombre y puerto de nuestro servidor.

Con esto tenemos mínimamente configurado nuestro servidor de integración para que busque cambios en el cvs cada 60 segundos, y de haberlos baje esos cambios, reconstruya el proyecto y deje los resultados para ser vistos con la aplicación web integrada.

2 comentarios:

phede dijo...

Muy bueno el producto este. Lo voy a agregar a mi caja de herramientas porque una de las tareas que más realizo todos los días es bajar todo el sourcesafe, compilar, desplegar, probar, etc etc.....

Saludos,
Fede

Luis Belloch dijo...

Hola, muy bueno el post, poca gente escribe (en español) sobre este tipo de cosas, está genial arrojar un poco de luz sobre el asunto.

¿Cuando el proceso de build tarda 4 o 5 horas en realizarse cómo integras continuamente? ¿compilas solo la "parte afectada"? ¿no sería mejor compilar diariamente para llevar un ciclo más estable de release? Trabajo como desarrollador en .NET y actualmente generamos el producto con NAnt. Pensé en la utilización de CruiseControl.NET o Draco.NET, ya que a veces integramos más de una vez en el día, pero no parece "muy práctico" de primeras...

En fin, de cualquier forma, este post y muchos otros (en ingles) me han lanzado a publicar un articulo en mi blog. Gracias por la inspiración.