Ayer por la tarde actualizamos a la versión 3 nuestro hudson y se rompió entero… como
llevaba un tiempo queriendo migrar el hudson
a jenkins decidimos que era un
buen momento para reorganizar todo el sistema de integración continua
y usar un truco para poder realizar tareas con condiciones desde ant, manejando las condiciones desde
las interfaz de hudson a partir de ahora jenkins. Explico a
continuación el problema y la solución adoptada en zylk.net.
En zylk.net tenemos todos los proyectos automatizados con
tareas de ant o
con tareas de maven. Personalmente nos gusta más ant aunque
usamos indistintamente cualquiera de las dos alternativa. Al tener las
tareas automatizadas con ant tenemos un problema típico que consiste
en como gestionar las partes del proyecto que son dependientes del
entorno de una manera cómoda. Hasta aquí el problema.
Las posibles soluciones que hemos ido trabajando son las
siguientes
- Crear tareas diferentes para cada entorno, por ejemplo tener
una tarea de compilado otra de empaquetado y otra de despliegue
distinta para cada entorno - Ser capaces de parametrizar la ejecución de las tareas en base
a ciertos valores que cambian - Disponer de tareas condicionales que se ejecutan o no en base a
ciertos valores de ciertas variables.
En este caso hemos modificado las corrientas de ant para que tengan
las siguiente estructura
<property name="deploy"
value="true" />
<target
name="deploy.check">
<condition
property="deploy-control">
<and>
<contains
string="${deploy}" substring="true"
/>
</and>
</condition>
</target>
<target if="${deploy-control}"
name="remote-deploy"
depends="deploy.check">
</target>
en este snipet de ant vemos dos tareas
- deploy.check
- remote-deploy
La primera es una tarea que lo que hace es comprobar el
valor de una variable ${deploy} y en base a su valor,
fija otra varible ${deploy-control}
La segunda que depende de la primera solo se ejecuta si la
variable ${deploy-control} existe
(if="${deploy-control}")
El
estado de la variable deploy se pude controlar desde tres puntos
- build.xml o properties asociado <property
name="deploy" value="true" />. - linea de comandos -Ddeploy = true.
- o desde la interfaz de jenkins como un parámetro de entrada de
la tarea de jenkins. Es decir desde la interfaz web del producto.
Con este pequeño cambio en las tareas de ant podemos
parametrizar las ejecuciones y en base a un check dentro del jenkins y
realizar tareas especificas para un entorno concreto. Por ejemplo pone
unos ficheros de configuración u otros dependiendo de valor de una
variable
<target name="environment.prod.check">
<echo message="Mege para produccion ${deploy.prod}
${environment.prod}" />
<condition
property="environment.prod">
<and>
<contains
string="${deploy.prod}" substring="true"
/>
</and>
</condition>
<echo message="Mege para produccion 2 ??? ${deploy.prod}
${environment.prod}" />
</target>
<target name="merge-prod"
if="${environment.prod}"
depends="init,environment.prod.check">
<echo message="se usara el context-prod.xml"
/>
<copy file="context-prod.xml"
tofile="META-INF/context.xml"/>
<copy
file="WEB-INF/web-prod.xml"
tofile="WEB-INF/web.xml" />
</target>
En este caso si desde la interfaz de jenkins ponemos
el valor true a la variable ${deploy.prod},
conseguiremos que el empaquetado generado tenga el web.xml y el
context.xml para el entorno productivo.
Estas cosas se
pueden hacer con tareas tipo if de ant pero no son estándares 100%