15 OctParado, pero no ocioso

Aunque estoy en las filas del INEM, es decir, en el paro, no estoy ocioso ni mucho menos.

Por un lado estoy bastante involucrado en la organización del Agile Open Spain 2009. Parece mentira que un evento tan sencillito, con un formato tan ligero como openspace y con tan “pocos asistentes” (hemos limitado las invitaciones a sólo 150), pudiera ser tan laborioso. Supongo que tiene que ver también con el hecho de que ninguno nos dedicamos a esto de organizar eventos, que estamos geográficamente dispersos y que es la primera vez que hacemos algo así. Y por si fuera poco, me tengo que preparar alguna cosilla para el Open como el “mortal kombat” con Xavi Gost (un ejercicio de TDD y programación en parejas “en vivo y en directo”, que queremos grabarlo y todo) o un breve discursito de bienvenida a los que vengáis.

Por otro lado, estamos constituyendo Agile Spain como asociación, lo cuál no es mucho, pero suma (o resta, según se vea). Igual que las “relaciones exteriores”. Mantener el contacto con Red.es y otros contactos que puedan ayudar a Agile Spain en el futuro es algo necesario, que a veces quizás ocupa más de lo necesario.

El grupo de Agile Spain en Madrid requiere un poco más de energía y para eso tengo que “soltar lastre” en otros asuntos. Pero es difícil dejar de hacer… porque me había comprometido, por ejemplo, a participar como revisor del libro de Carlos Blé sobre TDD y colaborar con una breve reseña sobre DDD. Buff… hago lo que puedo, Carlos. ;-)

También estoy arrancando un proyecto personal llamado agilismo.es. Pretendo que sea un portal donde ofrecer contenidos de calidad relacionados con las metodologías y prácticas ágiles. No os puedo contar mucho más porque hay que ir creando expectativa…

He estado preparando mi CV (ya os contaré sobre la única respuesta que he tenido hasta el momento) porque “a Dios rogando y con el mazo dando”, ¿no?

Y por si fuera poco, ahora me he dejado enredar por iExpertos.com (Gregorio Mena y Carlos Blé) para dar un pequeño curso en Tenerife sobre Buenas prácticas en Integración Continua, donde explicaré cómo montar un ecosistema software muy sencillo y las mejores prácticas que conozco para tener una integración continua decente. Teniendo en cuenta que los que vengan van a salir con “recetas” para irse a su casa y ponerse a jugar enseguida, creo que es tremendamente barato (apenas 35€), sobre todo si lo comparas con esos cursos de tres cifras que apenas te sirven para irte a tu casa y pensar en cómo pones en práctica todo aquello (si algún día siquiera tienes la oportunidad de hacerlo). Pero es tan barato porque en realidad se trata sólo de cubrir los gastos de mi desplazamiento y poco más. No hay un verdadero interés por parte de los organizadores (ni de mi mismo) de lucrarnos con esto. Hombre, si vais muchos quizás haya para darme un paseo por alguna otra isla. :-) Pero debo confesar que me gustaría comenzar a “redituar” todos estos esfuerzos.

Necesariamente, toda esta actividad hace que la regla del “no me aprietes que no te abarco” entre en juego. Hay iniciativas que arranqué con mucho cariño, como la lista de DDD en español, o algunas lecturas que quería ir resumiendo en este blog (que también tengo un pelín abandonado, lo sé).

¡Ah! Se me olvidaba, tengo dos pequeños a los que tengo que llevar y traer del cole y demás actividades. Menos mal que el mayor se baña solo. :-D

En fin, lo dicho, parado sí, pero no ocioso.

16 MarVersionado automático con Maven

Este fin de semana he estado jugando con maven-release-plugin con el objetivo de automatizar el versionado de mi código y, bueno, el resultado ha sido un tanto agridulce porque por un lado ha sido muy sencillo pero por otro me he encontrado con un defecto de esos que cuesta encontrar, sobre todo cuando no estás seguro de lo que tienes entre manos porque ni lo has hecho tú ni está suficientemente documentado.

La parte fácil

Antes que nada, os cuento lo que yo suelo hacer con el código cada vez que termino una iteración.

Supongamos que la versión actual es la 0.0.1-SNAPSHOT.

1) Me recorro todos los pom.xml donde he puesto 0.0.1-SNAPSHOT y le quito el -SNAPSHOT.
2) Hago commit de los pom.xml que he cambiado.
3) Etiqueto esta versión del código en el repositorio (en mi caso Subversion).
4) Vuelvo a recorrer todos los pom.xml para dejar la siguiente versión: 0.0.2-SNAPSHOT.
5) Hago commit de los pom.xml.

Y eso todas las veces…

Pues bien, resulta que hay un plugin de Maven que hace todo eso por mi: maven-release-plugin.

Antes de empezar yo aconsejo también hacer mvn clean install, pero no es obligatorio. Yo es que soy un poco obsesivo con estas cosas.

Para usarlo no puedo tener ningún “commit” pendiente, de lo contrario, el plugin se quejará. Es obligatorio también proporcionar la información de dónde está nuestro repositorio, para ello debemos incluir el apartado “scm” en los pom.xml que lo requieran (según los tengamos organizados):

   https://shopaas.googlecode.com/svn/trunk/shopaas  scm:svn:http://shopaas.googlecode.com/svn/trunk/shopaas  scm:svn:https://shopaas.googlecode.com/svn/trunk/shopaas 

El plugin sustituirá en estas cadenas los valores adecuados, por eso es aconsejable revisar cómo quedan estas secciones de los pom.xml las primeras veces.

Lo primero que hay que hacer es:

mvn release:prepare -DdryRun=true

Esta instrucción cubre los pasos 1, 2 y 3. La propiedad “dryRun” nos sirve para decirle al plugin si queremos o no hacer efectivos los cambios, si le damos el valor “true”, el plugin NO hará commit ni tag. También comprueba si hay dependencias con artefactos cuya versión aún es SNAPSHOT, pero esto no lo he probado, la verdad. Además, “release:prepare” ejecuta por defecto los siguientes “goals” sobre el proyecto: “clean verify”. Esto hace que se ejecuten las pruebas.

Cuando lo ejecutemos, por la consola Maven nos preguntará la versión de cada pom.xml (él no quita el “-SNAPSHOT” sino que pone la versión que nosotros le digamos). También nos pregunta cuál es el nombre con el que va a etiquetar esta versión en el repositorio de control de versiones. Y por último nos pregunta cuál es la versión que vamos a tener para trabajar después de este versionado (que suele ser la siguiente con el “-SNAPSHOT”). El plugin nos propone valores por defecto que podemos aceptar pulsando “intro”. Para cada pom.xml, la ejecución con “dryRun=true” nos dejará 3 ficheros: pom.xml.releaseBackup, pom.xml.tag y pom.xml.next, que se corresponden con el que tenemos antes de ejecutar (0.0.1-SNAPSHOT), el que se etiquetará como versión estable (0.0.1) y el que quedará en el “trunk” con la nueva versión de trabajo (0.0.2-SNAPSHOT). Pero el plugin no hará efectivos estos cambios porque le hemos dicho “dryRun=true”.

La parte difícil

Hasta aquí todo iba bien, pero el siguiente paso me dio problemas. Pero primero hay que ejecutar sin “dryRun” para que se hagan efectivos los cambios en SVN.


mvn release:clean release:prepare

release:clean sirve para limpiar los ficheros que haya podido dejar una ejecución anterior. También podemos usar releas:rollback para deshacer los cambios efectuados en SVN.

El primer obstáculo fue al usar el Maven embebido que viene con m2eclipse. Así que tuve que pasar a usar una instalación externa (concretamente la 2.0.9).

El segundo obstáculo fue al ejecutar el comando y encontrarme con el siguiente mensaje de error:

[INFO] Executing: cmd.exe /X /C "svn --non-interactive commit --file C:\Temp\maven-scm-2032301768.commit --targets C:\Temp\maven-scm-5209016095571570993-targets"[INFO] Working directory: C:\eclipseWorkspaces\MiTienda\shopaas[INFO] Tagging release with the label shopaas-0.0.1...[INFO] Executing: cmd.exe /X /C "svn --non-interactive copy --file C:\Temp\maven-scm-328141097.commit . https://shopaas.googlecode.com/svn/tags/shopaas-0.0.1"[INFO] Working directory: C:\eclipseWorkspaces\MiTienda\shopaas[INFO] ------------------------------------------------------------------------[ERROR] BUILD FAILURE[INFO] ------------------------------------------------------------------------[INFO] Unable to tag SCMProvider message:The svn tag command failed.Command output:svn: Commit failed (details follow):svn: File '/svn/tags/shopaas-0.0.1/domain/pom.xml' already exists

El caso es que hay un bug (¡cómo no!) que, para colmo, no parece estar claro si está del lado de Maven o de SVN. Parece que maven-release-plugin hace “svn copy” para crear el tag y que, a partir de la versión 1.5.1 de Subversion esto mismo ha comenzado a fallar. Así que hay que hacer manualmente la siguiente chapu:

# mvn release:prepare=> fails# svn up -r head # mvn release:prepare -Dresume

De esta manera, los ficheros en .svn que han quedado chungos se arreglan con “svn up” y luego se continúa por donde se había quedado (con -Dresume). Con Eclipse consiste en primero hacer “Team / Update” y a continuación ejecutar Maven con el goal “release:prepare” y el Parameter “resume” (al que tenemos que ponerle el valor “true” porque la configuración del launcher que propone m2eclipse no permite añadir un parámetro con nombre pero sin valor).

Llegados a este punto podemos revisar que en nuestro servidor de SVN se han creado tres nuevas revisiones con el siguiente comentario:
* [maven-release-plugin] prepare release shopaas-0.0.1
* [maven-release-plugin] copy for tag shopaas-0.0.1
* [maven-release-plugin] prepare for next development iteration

Los ficheros que son cambiados tras la ejecución (los pom.xml) podemos compararlos con las correspondientes versiones anteriores. En mi ejemplo, el mismo trozo del pom.xml que muestro más arriba queda como:

   https://shopaas.googlecode.com/svn/tags/shopaas-0.0.1  scm:svn:http://shopaas.googlecode.com/svn/tags/shopaas-0.0.1  scm:svn:https://shopaas.googlecode.com/svn/tags/shopaas-0.0.1 

Y en nuestro espacio de trabajo tenemos que la versión de los diferentes pom.xml ha quedado ahora como 0.0.2-SNAPSHOT, tal y como respondimos en su momento. También nos ha quedado un fichero release.properties con todas las versiones y trayectorias en SVN de los componentes versionados por este plugin.

Queda pendiente

Me queda aún por probar a realizar el despliegue de la nueva versión de manera automatizada. Para ello hay que usar el goal “release:perform”, que según parece ejecuta por defecto los goals “deploy site-deploy” después de obtener dicha versión desde el servidor de control de versiones.