Guía práctica de integración continua con Hudson Ubaldo Villaseca Jalasoft [email protected] RESUMEN Los beneficios de la integración continua; detección temprana de problemas de integración, métricas inmediatas, y disponibilidad constante de un build para pruebas / demos / releases, entre otros; han sido corroborados y aceptados durante los últimos años, pero la comunidad podrı́a no tener una idea práctica de cómo implantarla en sus organizaciones. Este artı́culo busca proveer de una guı́a para el despliegue y puesta en marcha de un ambiente de Integración Continua utilizando Hudson, una de las herramientas más preferidas y en constante evolución de la actualidad. Empezaremos mostrando las bases de obtener un build simple, para luego revisar tópicos avanzados como la inclusión de analizadores estáticos de código y tests funcionales automatizados dentro la generación del build. Palabras Clave integración continua, continuous integration, build machine, build automation, Hudson 1. INTRODUCCIÓN El “build” es el producto de software listo para ser desplegado en un ambiente de testeo, demo o producción. Todo el esfuerzo del equipo de desarrollo se ve reflejado en cada build de manera directa (programadores, artistas, documentadores) o indirecta (ingenieros de calidad, managers, product owners). Se denomina “integración” al proceso por el cual se incorporan cambios y agregados en el sistema en desarrollo, asegurando que, una vez integrado, éste funciona correctamente como un todo. Términos como daily build, nightly build, e integración continua hacen referencia a la frecuencia de este proceso. Entendemos por “funcionar correctamente” a que un build satisface los requerimientos funcionales y no funcionales defi- La copia digital o la impresión total o parcial de este trabajo, sea para uso personal o en clases, sólo está autorizada, respectivamente, a los empleados de Jalasoft o a la Fundación Jala. Las copias deben llevar en su primera página este aviso completo. Cualquier otro tipo de copia, la publicación de este material o su exhibición sobre servidores, o su difusión hacia listas de distribución requiere permiso expreso o pago previo de los derechos correspondientes. TechZone 2010, Septiembre 2010, Cochabamba, Bolivia. Derechos reserc 2009 - 2010 Jalasoft TechZone. vados nidos por el product owner, según el progreso esperado de la implementación en un momento dado. En la práctica, esto se hace a través de la ejecución de un conjunto de casos de pruebas, por niveles, haciendo correr primero aquellos más crı́ticos y susceptibles de fallar. Además de la frecuencia explicitada en el término, la integración continua, que abreviaremos CI, como práctica de ingenierı́a de software, establece un conjunto de prácticas que tiene como fin asegurar la obtención continua y exitosa de builds validados. Como detallaremos en las siguientes secciones, varias de estas prácticas pueden ser automatizadas parcial y completamente dada su naturaleza repetitiva. El presente artı́culo se organiza como sigue: Primero expondremos brevemente los conceptos más importantes de la integración continua. A continuación enumeraremos las herramientas en boga para la puesta en marcha de un ambiente CI, entre las cuales destaca Hudson, uno de los mejores servidores de CI de la actualidad. En la tercera sección, la parte práctica iniciará con la instalación y puesta en marcha de las herramientas sugeridas previamente, haciendo hincapié en Hudson. La cuarta sección detallará la configuración de un build job simple, el cual servirá de base para la quinta sección que expondrá conceptos avanzadas tales como la automatización de la ejecución de casos de prueba y el análisis estático de código. Finalmente, obtendremos las conclusiones del presente trabajo. 2. PRÁCTICAS Y BENEFICIOS DE LA INTEGRACIÓN CONTINUA CI busca convertir la integración en un “non-event” [5], algo que ocurre como parte del flujo diario y normal de trabajo. Un proceso de integración continua efectivo debe considerar las siguientes prácticas [6]: 1. Mantener un repositorio de fuentes con todos lo artefactos de software, no sólo código fuente. El repositorio debe contener todas las dependencias de tal manera de poderse generar un build inmediatamente y en cualquier lugar. Existen múltiples sistemas control de versiones, por ejemplo Subversion, Mercurial, Perforce, etc. 2. Automatizar el build. Debe poder generarse un build con un simple comando. Ejemplos de “build tools” son Make, Ant, MSBuild, Rake, etc. 3 3. Hacer el build auto-testeable. Una vez generado el build requiere validación. Se deben automatizar tanto los test de unidad utilizando un framework de unit testing (JUnit, MSTes, etc.), como los casos de prueba funcionales con herramientas como Watir, Watin, SilkTest, etc. 3. El build job descarga los últimos cambios del SCM y procede a ejecutar los build scripts escritos en Ant, MSBuild, Rake, etc., los cuales además hacen correr los casos de prueba automatizados, y los analizadores estáticos de código, con el fin de validar el build. 4. Una vez el build job fue completado con éxito o fallo, se notifican los resultados por correo a los programadores y a toda persona interesada. 4. Subir código diariamente. Mientras mayores sean los intervalos de commit / push, mayores problemas de integración ocurrirán. Subiendo código al menos una vez por dı́a se asegura un rápida y efectiva integración. 5. Si el build fue un éxito, se lo copia un folder compartido para fácil acceso. 5. Cada commit / push debe generar un build. De esta manera cada commit / push es validado, y en caso de problemas, éstos son resueltos inmediatamente. 3. 6. Asegurar que la generación de builds es lo suficientemente veloz (<= 10 minutos). Ası́ se identifican problemas rápidamente. 3.1 HERRAMIENTAS Considerando lo anteriormente expuesto, proponemos las siguientes herramientas: SCM Se sugiere Mercurial o Subversion. 7. Testear en un clon del ambiente de producción. Jamás testear en un ambiente de desarrollo. Es frecuente pasar por alto errores debido a que no se reproducen en ambientes de desarrollo. Mercurial es un sistema de control de versiones descentralizado, multi-plataforma, escrito en Python, que permite un desarrollo totalmente distribuido y colaborativo. Por ejemplo, los programadores realizan commits sin tener un servidor disponible, trabajando en modo offline, y aprovechando todas las ventajas de un SCM, para posteriormente hacer el respectivo update, merge y push al server una vez entran en modo online. La principal desventaja encontrada hasta el momento recae en la práctica no disponibilidad de herramientas de estadı́sticas de repositorio como StatCVS. Otra desventaja menor, pero subsanable de alguna manera con la extensión Keyring, es el no soporte para Windows Authentication [8]; aunque, como veremos más adelante, algunos de los servicios de Mercurial como HgWeb sı́ soportan este tipo de autenticación. 8. Hacer fácil la obtención de los últimos builds. El feedback del cliente es extremadamente importante, por tanto se necesita que éste tenga acceso a los últimos builds en todo momento. 9. Todos pueden ver los resultados del build job. La visibilidad es la clave del éxito cuando se quiere implantar CI en un equipo de desarrollo. 10. Automatizar el despliegue. Al ser este un proceso repetitivo, conviene automatizarlo más aún si se requiere hacer el testeo manual en múltiples ambientes. Subversion lleva ya varios años de desarrollo por lo cual es muy estable, y posee una amplia base de conocimiento en Internet; sin embargo, al contrario de Mercurial, no es descentralizado por lo cual exige del usuario estar siempre conectado al servidor para aprovechar las ventajas del SCM. Otra desventaja mayor es su soporte forzado para branches y tags que acarrea problemas en tareas de diff y merge [10]. Frente a Mercurial, tiene como ventajas la existencia de varias herramientas de estadı́sticas de repositorio como StatSVN; además de un excelente soporte para Windows Authentication, tanto del lado del servidor como de los clientes. La implementación de estas prácticas asegura los siguientes beneficios: 1. Los programadores detectan y arreglan problemas de integración de manera continua. 2. Verificación inmediata y automática de los builds. 3. Disponibilidad constante de un build actual para testing, demo o releases. Dentro del contexto de CI, necesitamos que un nuevo build sea generado por cada commit / push, lo cual es completamente posible dado que ambas herramientas soportan hooks. Un hook es un mecanismo de automatización que permite interceptar eventos en el repositorio, tales como commits / pushes, y ejecutar un acción que para nuestros propósitos será ejecutar un build job. 4. Obtención periódica de métricas. 5. Levanta la moral del equipo. 2.1 HERRAMIENTAS Componentes Proponemos el siguiente esquema para el caso de estudio que nos atañe : 3.2 Herramientas de Automatización del Build La generación del build incluye tareas diarias como: 1. Los programadores hacen commit / push al SCM diariamente. • Compilar el código fuente a binario. 2. El SCM notifica al Build Machine para que arranque un build job por cada commit / push. • Descargar / actualizar los 3rd-party libraries. 8 3.3 Herramientas de Automatización del Testeo 3 HERRAMIENTAS Figura 1: Componentes de un sistema CI [4]. Adaptado para Jalasoft. • Empaquetar los binarios. Basados en nuestra experiencia, dos factores se deben tomar en cuenta a la hora de elegir un build tool: facilidad de creación y mantenibilidad de los scripts, y disponibilidad de extensiones pre-existentes para tareas propias de un proyecto. Por ejemplo: • Desplegar la aplicación en un ambiente limpio que no sea de desarrollo. • Ejecutar los casos de prueba, unitarios y funcionales. • Generación de la documentación y / o release notes. • Ant, a pesar de sus múltiples falencias, cuenta con un set completo de tasks para BlackBerry [1]. Los build tools automatizan parcial o totalmente este conjunto [2], si bien no están limitadas y ofrecen capacidades de extensión. Por supuesto se puede optar por la automatizar el build desde cero utilizando scripting simple como batch files en Windows o shell scripts en Linux. El propósito final es poder generar el build con una sola y sencilla llamada a lı́nea de comandos. • Los scripts base de MSBuild, para proyectos .NET, son automáticamente generados por Visual Studio. 3.3 Herramientas de Automatización del Testeo Existen varios tipos de testeo. Detallaremos 3 de ellos y sólo desarrollaremos los primeros 2: Herramientas populares, según la plataforma sobre la cual se ejecutan, son: • Unit testing • Java: Ant, Maven • Testeo funcional • .NET: MSBuild, NAnt • Testeo de carga • Ruby: Rake 3.3.1 • C / C++ / Objective-C: Make Unit Testing Dadas las caracterı́siticas simples del testeo unitario, la mayorı́a de los frameworks disponisbles son recomendados. Para proyectos en .NET, usamos el framework incluido en Visual Studio denominado MSTest debido a su excelente integración con el IDE. Adicionalmente, es necesario valerse En general la plataforma no deberı́a afectar la elección de una u otra. Es posible automatizar por completo una solución de .NET con Make, o un proyecto de Java con Rake. 9 3.4 CI Server 3 HERRAMIENTAS Figura 2: Basic structure of a CI system [9]. de bibliotecas de mocking and stubbing como Moq o Rhino Mocks. 1. Obtención de lo fuentes y artefactos del repositorio. No es propósito de este trabajo ahondar en cómo realizar y automatizar el unit testing, sin embargo es importante recalcar su importancia dentro un esquema CI. 3. Empaquetamiento de los binarios. 3.3.2 2. Compilación. 4. Despliegue en el ambiente limpio. 5. Validación del build. Testeo Funcional Existen varios frameworks y herramientas para la automatización del testeo funcional. Por ejemplo, para automatización de aplicaciones Web tenemos Watir, Watin, Selenium, SilkTest, etc; para automatización de aplicaciones Windows AutoIT, AutoHotKey, SilkTest, etc.; si se quiere automatizar servicios Web, sin lugar a dudas se recomienda soapUI debido a su amplia funcionalidad y estar en constante desarrollo, además de tener un versión open source y gratuita. Para todos los casos, sin embargo, debe verificarse el soporte para lı́nea de comandos, caso contrario no será posible integrarlo con el servidor CI. 6. Copiar al repositorio de builds. 7. Comunicación de resultados. Denominamos “build job” a la configuración de las tareas previamente enumeradas para la obtención de un build especı́fico. A pesar de haber sido el CI server de preferencia por varios años, CruiseControl ha perdido popularidad y nuevos desarrollos declinan con el paso del tiempo [3]. Como contraparte, Hudson se ha convertido en el CI server más popular, y de mayor desarrollo, de la actualidad [7], debido a su sencillez de uso y gran extensibilidad por medio de plug-ins. Una vez escogida la herramienta y preparados los tests, se procederá a incluir las tareas relacionadas (tasks) dentro del build script. 3.3.3 3.4.1 Testo de Carga (Load Testing) Algunos proyecto de Jalasoft han tenido buenas experiencias con Apache JMeter. Tomar en cuenta que JMeter no reemplaza a herramientas de testeo funcional como Watir. 3.4 Hudson Escrito en Java, basado en servlets, Hudson permite la administración de build jobs (creación, configuración, ejecución y monitoreo) por medio de una interfaz Web intuitiva. Su desarrollador primario es Kohsuke Kawaguchi. CI Server Entre las caracterı́sticas más importantes destacan: El CI server está encargado de orquestar la puesta en marcha de la generación y validación del build, y de la comunicación de los resultados a las personas interesadas. Ver figura 2. 1. Fácil instalación / actualización. Comúnmente el CI server ejecuta las siguientes tareas: 2. Fácil configuración de Hudson y de los build jobs. 10 3.5 Herramientas y Requisitos Implı́citos 4 3. Builds distribuidos y con soporte para multi-plataforma. INSTALACIÓN Y PUESTA EN MARCHA publicados en Hudson, como data grids o charts, de tal manera de optimizar la revisión y corrección de problemas. 4. Extensibilidad especı́fica a través de soporte para plugins. Ahondaremos en este tema más adelante. 5. Extensibilidad y mantenibilidad derivada al ser open source. 3.5 Herramientas y Requisitos Implícitos Incluye compiladores, runtimes (JRE, .NET), y otros que dependen de la plataforma de desarrollo. Sus principales falencias son: 3.6 Herramientas de Apoyo Llamamos “herramientas de apoyo” a las herramientas y sistemas que no participan directamente en el CI, pero que apoyan a los herramientas / sistemas CI para propósitos determinados. Necesitaremos las siguientes para el presente trabajo: 1. Sin soporte para múltiples repositorios en un buid job individual, escenario frecuente en Mercurial. 2. El soporte para encadenamiento de build jobs a través de fingerprints es algo forzado. 1. Apache HTTP 2.2 (en un instalación por defecto) Plug-ins. Como se mencionaba anteriormente, Hudson puede extenderse a través de plug-ins. Éstos se clasifican de la siguiente manera: (a) mod auth sspi. Requeridos para Windows Authentication. (b) mod wsgi y mod alias. Requeridos para la integración de Mercurial con Apache. • Source code management. Hudson soporta nativamente Subversion y CVS, sin embargo puede extenderse para Perforce, Team Foundation Server (TFS), Mercurial, Git, etc. (c) mod dav, mod dav svn y mod authz svn. Requerido si se va a integrar Subversion con Apache. (d) mod proxy y mod proxy ajo. Requerido para la integración de Tomcat, y de otros Web servers, con Apache. • Build triggers. Permiten iniciar un build a través de diferentes eventos y según ciertas condiciones. Por ejemplo, iniciar un build por IRC. 2. Tomcat 6.0 (se puede probar con la versión 7). Requerido para Hudson y para habilitar Windows Authentication a través de AJP Connector. • Build tools. Hudson soporta nativamente Maven, Ant, shell scripts y Windows batch commands. Hay plug-ins para MSBuild, ejecutar Rake tasks, etc. Cabe recalcar que la elección de las herramientas de apoyo obedece a la información disponible en Internet, por tanto éstas pueden ser reemplazadas por equivalentes. Por ejemplo, se podrı́a reemplazar Apache HTTP 2.2 por IIS. Recalcar además que la seguridad no fue tomado en cuenta, es por eso que no se hace mención al uso de HTTPS para las conexiones. • Build wrappers. Permiten ejecutar acciones antes, durante y después de ejecutado un build job. Por ejemplo, el plug-in para VMware permite encender una máquina virtual antes del build job y apagarla después de completado. • Build notifiers. Hudson tiene soporte nativo para notificaciones por email. Existe extensiones para Twitter Plugin, Nabaztag, etc. 4. • Y otros. 3.4.2 INSTALACIÓN Y PUESTA EN MARCHA Se recomienda tener un servidor dedicado con al menos 1GB de RAM y el mejor procesador que se pueda otorgar a este fin, considerando que CI hace énfasis en que las corridas de los build job sean lo más cortas posibles. Plug-ins de Reporte Vale tratar por separado a los a los plug-ins de reportes dado su impacto en el proceso de desarrollo. 4.1 Java Descargar la versión más reciente del JDK. El presente usará la versión 6u21 (1.6u21). Proceder a instalar y dejar las opciones por defecto en cada paso. Los plug-ins de reporte son simples procesadores de información externa a Hudson para que éste pueda, dependiendo el caso, alterar el flujo o los resultados de un build job, y en otros mostrar la información externa formateada apropiadamente para Hudson. 4.2 Microsoft .NET Framework Descargar la versión más actual del framework de .NET. Proceder con la instalación con las opciones por defecto. Hudson soporta nativamente la generación de reportes de JUnit y javadoc. Entre los plug-ins disponibles destaca Violations que soporta múltiples analizadores código como StyleCop, FxCop, Checkstyle, FindBugsŹ, etc. Basado en los resultados de los analizadores un build podrı́a ser considerado inestable por Hudson; estos mismos resultados son 4.3 Apache Tomcat Obtener la versión más actual de Tomcat. Proceder con la instalación dejando las opciones por defecto, excepto en los siguientes pasos: 11 4.4 Apache HTTP Server 4 Paso 3. 4.3.2 INSTALACIÓN Y PUESTA EN MARCHA Configuración del conector AJP El conector AJP posibilita la comunicación del servidor Apache HTTP con Tomcat. En el archivo %TOMCAT HOME%\conf\ server.xml, descomentar la siguiente sección; actualizar o copiar los parámetros si es necesario. <Connector port="8010" enableLookups="false" tomcatAuthentication="false"redirectPort="8444" protocol="AJP/1.3" URIEncoding="UTF-8" maxThreads="200" minSpareThreads="25" maxSpareThreads="75"/> En el mismo archivo, comentar la siguiente sección para deshabilitar el acceso normal por el puerto 8080: <!--<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />--> 4.4 Apache HTTP Server Apache proveerá servicios de autenticación Windows (IWA) a todos los sistemas. Descargar la última versión de Apache. Usaremos la versión 2.2.16. Durante la instalación, podrı́a ser necesario cambiar algún parámetro en el paso “Server Information”, como por ejemplo el email de administrador. El resto de los pasos pueden ser dejados con los valores por defecto. Paso 5. Establecer el nombre de usuario y contraseña para el Tomcat Administrator. 4.4.1 Verificación.. Abrir en un browser la dirección http:// uvillasecv-dv01:8080. 4.3.1 Módulos Adicionales Obtener las versiones más actuales de los módulos mod sspi y mod wsgi. Verificar la compatibilidad de mod wsgi con la versión de Python instalada. Para el presente usaremos las versiones 1.0.4-2.2.2 y 3.3 respectivamente. Optimización Copiar los módulos a la carpeta %APACHE HOME%modules. Renombrar binario de mod wsgi a mod wsgi.so. En el archivo %TOMCAT HOME%\conf\web.xml, verificar las siguientes configuraciones, si es necesario cambiar o agregar. 4.4.2 Configuración de los Módulos Agregar las siguientes lı́neas en el archivo de configuración %APACHE HOME%\conf\httpd.conf: <servlet> <servlet-name>jsp</servlet-name> <servlet-class> org.apache.jasper.servlet.JspServlet </servlet-class> <init-param> <param-name>fork</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>development</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>checkInterval</param-name> <param-value>0</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> LoadModule sspi_auth_module modules/mod_auth_sspi.so LoadModule wsgi_module modules/mod_wsgi.so Además descomentar las siguientes: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so 4.4.3 Configuración de la Integración con Tomcat En el archivo %APACHE HOME%\conf\httpd.conf agregar las siguientes lı́neas para habilitar el acceso a Tomcat a través de Apache: # Tomcat integration Listen 8080 NameVirtualHost *:8080 12 4.7 Software de Demo 4 4. Editar el archivo %MERCURIAL HOME%\ contrib\hgweb.wsgi. Asegurarse de que config apunte al archivo hgweb.config recientemente creado, además de al folder lib <VirtualHost *:8080> ServerName localhost ErrorLog "c:/Program Files/Apache Software Foundation /Apache2.2/logs/ajp.error.log" CustomLog "c:/Program Files/Apache Software Foundation /Apache2.2/logs/ajp.log" combined # Path to repo or hgweb config to serve config="c:\Program Files\Mercurial\contrib\ hgweb.config" <Proxy *> AddDefaultCharset Off Order deny,allow Allow from all </Proxy> # Uncomment and adjust if Mercurial is not... import sys; sys.path.insert(0, "c:\Program Files\Mercurial\lib") ProxyPass / ajp://localhost:8010/ ProxyPassReverse / ajp://localhost:8010/ </VirtualHost> 4.5 import os os.environ["HGENCODING"] = "UTF-8" 5. Editar el archivo %APACHE HOME%\httpd.conf para incluir: Python Mercurial corre sobre Python. La versión usada para el presente es 2.6.5. WSGIScriptAlias /techzone2010 "C:\Program Files \Apache Software Foundation\Apache2.2\cgi-bin \hgweb.wsgi" <Directory "C:\Program Files\Apache Software Foundation\Apache2.2\cgi-bin"> AllowOverride None Options None Order allow,deny Allow from all Una vez descargado proceder a instalarlo. Seleccionar en el primer paso la opción “Install for all users”; dejar las opciones por defecto para los siguientes. 4.6 Mercurial Obtener la última versión de Mercurial. Para el presente, usaremos la versión 1.6.3. AuthName "Hades Main Revision Control System" AuthType SSPI SSPIAuth On SSPIAuthoritative On SSPIDomain SITOCDC01 SSPIOfferBasic On SSPIOfferSSPI On SSPIUsernameCase lower SSPIOmitDomain On Require valid-user </Directory> Proceder a su instalación dejando las opciones por defecto para cada paso. 4.6.1 INSTALACIÓN Y PUESTA EN MARCHA Creación del Repositorio Crear un folder “Mercurial Repositories” en la raı́z de una partición. Situarese dentro este folder y crear un nuevo repositorio con el comando: 6. Verificar la instalación apuntando en un navegador a http://uvillasecav-dv01/techzone. $> hg init TechZone2010 Mercurial habrá creado un folder .hg; ingresar en éste y crear un archivo de nombre hgrc con el siguiente contenido, los parámetros a conveniencia: [web] [email protected] description=TechZone 2010 Revision Control System push_ssl=false allow_read="ubaldo villaseca" allow_push="ubaldo villaseca" 4.6.2 4.7 Integración con Apache 1. Descomprimir los scripts de Mercurial contenidos en %MERCURIAL HOME%\library.zip en el folder %MERCURIAL HOME%\lib Software de Demo Para las demostraciones usaremos log4net que es un framework de logging con soporte para múltiples salidas. Los unit test de log4net están basados en NUnit. Las versiones que usaremos son 1.2.10 y 2.5.7 respectivamente. Abrir el archivo log4net.sln y proceder con la migración hacia el Visual Studio de preferencia, en nuestro caso Visual Studio 2008. Una vez migrado, probar que el building no falla abriendo una lı́nea de comandos en el folder log4net1.2.10\src y ejecutando: 2. Mover el folder %MERCURIAL HOME%\Templates a %MERCURIAL HOME%\lib\Templates 3. Crear un archivo hgweb.config en %MERCURIAL HOME%\contrib con el siguiente contenido: [paths] techzone2010 = C:\Mercurial Repositories\TechZone2010 13 $> msbuild log4net.sln 4.8 Hudson 4 INSTALACIÓN Y PUESTA EN MARCHA Si no se presentan errores, subir el código al repositorio central de acuerdo a las siguientes directrices: 1. Si no se tiene un cliente de Mercurial disponible, bajar TortoiseHg. 2. Clonar el repositorio central. $> hg clone http://uvillasecv-dv01/techzone/techzone2010 3. Una vez clonado el repositorio central, se recomienda habilitar la extensión Keyring editando el archivo .hg\hgrc y agregando: [extensions] mercurial_keyring= [auth] default.schemes = http https default.prefix = uvillasecv-dv01/techzone default.username = Ubaldo Villaseca <[email protected]> 4. Copiar todos los archivos y directorios de log4net al repositorio recientemente clonado. 5. Crear un archivo .hgignore en la base del directorio con el siguiente contenido ^[Tt]est[Rr]esults$ .*[Rr]e[Ss]harper.* .*\.[Cc]ache$ ^(release|Release)$ ^(debug|Debug)$ ^(\.svn|\.hgsvn|ignore|Ignore|bin|Bin|obj|Obj)$ ^.*\.(o|lo|la|DS_Store|bak|class|exe|dll|mine|obj|ncb| log|idb|pdb|cod|jad|csl|debug|rapc|orig|cso)$ .*\.(ilk|msi|res|pch|suo|exp|cvs|CVS|user|rej)$ .*\..*~.*$ [tT]humbs.db$ .*~$ ~.*$ .*findbugs_errors\.xml$ .*checkstyle_errors\.xml$ .*FxCopResults\.xml$ .*build_number.* 6. Proceder a hacer commit y push con: $> hg commit $> hg push 4.8 Figura 3: Página principal de Hudson. 6. En System Variables agregar un nueva variable HUDSON HOME que apunte a C:\hudson. 7. Guardar y cerrar. 8. Se recomienda adicionalmente reiniciar Tomcat. Instalar Hudson simplemente copiando a %TOMCAT HOME%\ webapps el archivo hudson.war descargado anteriormente. Iniciar Hudson apuntando a la dirección http://uvillasecv-dv01: 8080/hudson; verificar que Hudson creó sus archivos en HUDSON HOME, si no, reinstalar. 4.8.1 Habilitar el Soporte para Windows Authentication Editar el archivo APACHE HOME\conf\httpd.conf. En la sección “Tomcat integration” anteriormente configurada, dentro el tag VirtualHost, agregar la siguiente configuración: Hudson Descargar la versión más actual de Hudson. Establecer la variable entorno HUDSON HOME: <Location /hudson> # authentication AuthName "TechZone Build Machine" AuthType SSPI SSPIAuth On SSPIAuthoritative On SSPIDomain JALASOFT SSPIOfferBasic On SSPIOfferSSPI On SSPIUsernameCase lower Require valid-user </Location> 1. Crear un folder ‘hudson’ en la raı́z de una partición, por ejemplo C:\hudson. Aquı́ se guardaran toda la información de configuración de Hudson y los build jobs. 2. Abrir el Control Panel. 3. System. 4. Advanced System Settings. 5. Environment Variables. Guardar y reiniciar Apache HTTP. 14 5 4.8.2 Habilitar la Seguridad CREACIÓN DE UN BUILD JOB SIMPLE Configurar el soporte para Mercurial: Por defecto Hudson brinda acceso total a todos los usuarios, por lo cual es necesario establecer la configuración de seguridad. 1. Click en Add Mercurial. 2. En Name poner DefaultMercurial. 1. Navegar hasta Manage Hudson. Ver Figura 3. 3. En Installation Directory escribir c:\Program Files\Mercurial 2. Una vez dentro, hacer click en “Configure System”. 4. En Executable escribir INSTALLATION\hg.exe 3. Dentro, habilitar la seguridad chequeando en “Enable security” 5. Cliquear Use Repository Caches. Configurar el soporte para MSBuild: 4. Se presentará un menú con varias opciones. En “Security Realm”, seleccionar “Delegate to servlet container”. 1. En MSBuilder click en Add. 5. En “Authorization” seleccionar “Matrix-based security”. 2. En name poner DefaultMSBuild. 6. Agregar un usuario escribiendo el nombre de usuario en “User/group to add”, incluir el dominio, todo en minúsculas. 3. En Path To msbuild.exe escribir c:\WINDOWS\ Microsoft.NET\Framework\v4.0.30319\MSBuild.exe 7. Otorgar todos los permisos. Configurar el correo electrónico: 1. Ir a E-mail Notification 2. En SMTP server escribir sitocex01. 3. En System Admin E-mail Addres escribir Ubaldo Villaseca <[email protected]> 4. Alternativamente hacer click en “Test configuration by sending e-mail to System Admin Address” para verificar el buen funcionamiento del correo electrónico. Guardar la configuración. 5. 8. Hasta aquı́, salvar la configuración. La próxima vez que se ingrese a Hudson, el usuario configurado deberı́a ser logueado automáticamente si se usa un browser con soporte para Windows Authentication, si no un diálogo de autenticación básica HTTP será mostrado. 4.8.3 2. En Job name escribir “TechZone2010” 3. Seleccionar Build a free-style software project. 4. Click en OK. Plugins Para el presente, necesitamos los siguientes plug-ins: MSBuild Plugin, NUnit Plugin, Mercurial Plugin, Email-ext plugin y Violations. Ir a Manage Hudson > Manage Plugins > Available, buscar y seleccionar cada uno de ellos. Una vez instalados, reiniciar Hudson o Tomcat. 4.8.4 CREACIÓN DE UN BUILD JOB SIMPLE 1. En el portal principal, hacer cliquear en New Job. Completar el Resto de la Configuración Volver a Manage Hudson > Configure System. 1. En JDK, hacer click en Add JDK. 2. En nombre escribir JDK 1.6. 3. Destiquear la opción “Install automatically”. 4. En JAVA HOME poner c:\Program Files\Java\jdk1.6.0 21 15 6 Procedemos a configurar los parámetros del build: TAREAS AVANZADAS 3. Hacer click en ‘Advanced’ 4. Agregar Triggers seleccionando el evento en el combo box Add a Trigger, excepto para Before-Build. Habilitar tanto para “Send To Recipient List” como para “Send To Committers”. 1. Cliquear en “This build is parameterized”. 2. Click en Add Parameter > String Parameter. 3. En Name poner “Configuration” y en Default Value “Debug”. En Description “This parameter determines the compilation configuration that can be either Debug or Release” La configuración básica del build está lista. Guardamos y ejecutamos haciendo click en Build Now. Ver Figura 3. 6. TAREAS AVANZADAS 6.1 Unit Tests 4. Cliquear nuevamente en Add Parameter > String Parameter. El código fuente de log4net, tal cual es distribuido, no incluye soporte para la ejecución de sus unit tests usando MSBuild, por lo cual deberemos actualizar el archivo tests\src\ log4net.Tests.csproj. Agregar las siguientes lı́neas inmediatamente después del proyecto: 5. En Name escribir “Version” y en Default Value “1.2.10” Configuración del repositorio de código. 1. Ir a Source Code Management. <Target Name="Test" DependsOnTargets="Build"> <Exec IgnoreExitCode="true" Command="&quot; c:\Program Files (x86)\NUnit 2.5.7\bin\net-2.0\ nunit-console.exe&quot; \bin\Debug\log4net.Tests.dll /xml=nunit-results.xml" /> </Target> 2. Seleccionar Mercurial. 3. En Mercurial Version seleccionar DefaultMercurial. 4. En Repository URL poner http://uvillasecv-dv01/ techzone/techzone2010 Reemplazar los paths según convenga y subir al repositorio. 5. En Branch escribir default 6. En Repository browser seleccionar hgweb. En URL poner http://uvillasecv-dv01/techzone/techzone2010 Al contrario de Subversion, Mercurial no soporta Windows Authentication, lo que nos obliga a establecer manualmente el usuario que accederá al repositorio desde Hudson. Para esto, creamos un archivo Mercurial.ini en %MERCURIAL HOME% con los siguientes datos, se recomienda crear un usuario exclusivo en Active Directory para este propósito: [auth] mercurial.prefix = uvillasecv-dv01 mercurial.username = JALASOFT\TechZoneRobot mercurial.password = xxx mercurial.schemes = http 6.2 Configuración de la construcción del software: StyleCop StyleCop es una herramienta de análisis estático de código distribuida gratuitamente por Microsoft. Descargar e instalar la versión más reciente; asegurarse de habilitar el soporte para MSBuild. 1. Ir a Build y hacer click en Add build step > Build a Visual Studio Project or solution using MSBuild. 2. En MsBuild Version seleccionar DefaultMSBuild. Editar el archivo src\log4net.csproj, agregar la siguiente lı́nea inmediatamente después de 3. En MsBuild Build File escribir src\log4net.sln <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/> Configuración de notificaciones: <Import Project="$(ProgramFiles)\MSBuild\Microsoft\ StyleCop\v4.3\Microsoft.StyleCop.targets" /> 1. Ir a Post-build Actions y seleccionar Editable Email Notification. Guardar y subir al repositorio. 2. En Global Recipient List poner [email protected] Editar el build job. 16 8 1. Ir a Post-build Actions y cliquear en Report Violations. BIBLIOGRAFÍA 3. Guardar. 2. En stylecop escribir **\StyleCopViolations.xml 7. 3. En Source Path Pattern escribir ** CONCLUSIONES Hudson es uno de las mejores build machine servers open source de la actualidad. Debido a su facilidad de instalación y uso, además de sus casi ilimitadas capacidades de extensión, se recomienda implantarlo en aquellos proyectos que todavı́a no cuenten con un build machine, o que presenten problemas y / o limitaciones en su build process. 4. Guardar. Ejecutar el build job. Adicionalmente, se recomienda prestar siempre atención a las prácticas de CI; si bien proyectos legados podrı́an no aplicar la totalidad de ellas, deberı́a desarrollarse un plan de migración dados los beneficios listados en este artı́culo. 8. 6.3 BIBLIOGRAFÍA [1] bb-ant-tools, Blackberry Ant Tools [online]. Disponible en: http://bb-ant-tools.sourceforge.net. (Accedido en Agosto 2010). 9 [2] Wikipedia, Build automation [Wikipedia (Inglés)]. Disponible en: http://en.wikipedia.org/wiki/Build_automation. (Accedido en Agosto 2010). 9 [3] Ohloh, CruiseControl [online]. Disponible en: http://www.ohloh.net/p/200. (Accedido en Agosto 2010). 10 [4] Duvall, P. M., Matyas, S., & Glover, A. Continuous Integration: Improving Software Quality and Reducing Risk. Indiana, USA: Addison Wesley. (2007). 9 [5] Fowler, M. (c. 1999). Continuous Integration (versión original). [online martinfowler.com]. http://martinfowler.com/articles/ originalContinuousIntegration.html. 7 [6] Fowler, M. (c. 2006). Continuous Integration (versión actualizada). [online martinfowler.com]. http://martinfowler.com/articles/ continuousIntegration.html. 7 [7] Hudson. [online ohloh] http://www.ohloh.net/p/hudson (Accedido en Julio de 2010). 10 [8] Kerberos-based HTTP authentication support planed? [online Mercurial mailing list] http://www.selenic. com/pipermail/mercurial/2008-March/018235.html (Post 2008). 8 [9] Whitehead, N. Continuous integration with Hudson. [JavaWorld.com online]. http://www.javaworld.com/ javaworld/jw-12-2008/jw-12-hudson-ci.html (Post 2008). 10 [10] Why Subversion sucks. [The Chaos Computer Club Cologne Wiki online]. https://wiki.koeln.ccc.de/ index.php?title=Why_Subversion_sucks (2010). 8 Ejecutar un Build Job por Cada Commit / Push Para que Hudson arranque un build job en cada push al server, necesitamos configurar un hook en repositorio dados los siguientes pasos. Configurar Hudson para que soporte arrancar un build por URL: 1. Editar el build job. 2. Ir a Build Triggers, cliquear Trigger builds remotely. 3. En Authentication Token escribir un password que será usando para arrancar los build por URL. Por ejemplo t3chz0ne2o1o. 4. Guardar. Descargar la versión más reciente de wget. Copiarlo a una ubicación conocida, por ejemplo C:\wget\wget.exe. En el servidor de Mercurial, ir al repositorio al que agregaremos un hok. 1. Abrir el archivo .hg\hgrc 2. Agregar la siguiente configuración, el usuario provisto debe tener privilegios de acceso y ejecución en Hudson: [hooks] changegroup=C:\wget\wget.exe --delete-after --http-user=JALASOFT\TechZoneRobot --http-password=xxx "http://uvillasecv-dv01:8080 /hudson/job/TechZone2010/buildWithParameters? token=t3chz0ne2o1o\&cause=Modifications to the source code were pushed." 17