maven-versions-plugin

Tenemos proyectos maven gigantes, con subproyectos que a su vez tienen más subproyectos. Estos a su vez tienen dependencias de otros proyectos nuestros maven también gigantes, con subproyectos y más subproyectos y estos a su vez … Con todo esto, el control de las versiones de nuestros jar es un pequeño infierno. Son muchos jar y muchos <dependency> esparcidos por los pom.xml de muchos proyectos. Actualizar una versión de un jar requiere ir recorriendo todos los pom.xml buscando <dependency> de ese jar y actualizar o no a la nueva versión.

Con la intención de ayudarnos a cambiar todos esos números, hice hace mucho tiempo un plugin de cambio de versiones. Aunque mi intención era buena y el plugin se usó algunas veces, la realidad cae por su propio peso. El plugin ahorraba trabajo, pero seguía siendo un poco engorroso de usar y dejó de usarse.

La siguiente aproximación fue poner en el pom.xml padre (de esos tenemos sólo tres o cuatro) unas properties con la versión deseada de cada jar. Tanto en la definición de la versión del proyecto como en las dependencias usábamos la property correspondiente. Nuevamente un fracaso, podemos tener cerca de un centenar de jars y un centenar de properties en los pom.xml de más alto nivel son muchas properties.

Así que actualmente nuestra versión de desarrollo es permanentemente 1.0-SNAPSHOT. Cuando hacemos una entrega a cliente, creamos una rama SVN y en esa rama, con un script, modificamos todos los 1.0-SNAPSHOT de todos los pom.xml por el nuevo número de versión para ese cliente.

La aproximación que quiero intentar ahora es una sola versión para todos los jar de un proyecto maven y subproyectos. Cuando se cambia la versión, se cambia para todos los jar de ese proyecto maven. En una primera intentona, en el proyecto padre, definí una property con la versión, estilo <proyecto.version>2.1-SNAPSHOT</proyecto.version>. y en todos los pom.xml, tanto en los <parent> como en los <version> de definición del jar puse ${proyecto.version}. Por ejemplo, en el pom.xml padre quedaría así

<project>
   <properties>
      <proyecto.version>2.1-SNAPSHOT</proyecto.version>
   </properties>
   <groupId>com.chuidiang</groupId>
   <artifactId>miproyecto</artifactId>
   <version>${proyecto.version}</version>
   …

 

pero empezamos con los problemas. Según maven, sí podemos poner variables ${variable} en las <version> de los <dependency>, pero no en los <version> de definición de proyecto o <parent>. Curiosamente maven no debe tener esto muy bien implementado y si lo haces, no protesta si compilas desde el proyecto raíz, pero sí lo hace si compilas desde los subproyectos.

Así que dejamos estas versiones de nuevo "a pelo", sin variables. Eso sí, definimos las properties para las dependencias de los otros proyectos. Como sólo tenemos tres o cuatro proyectos gordos de maven, sólo son dos o tres properties como mucho (bueno, alguna más hay). Así que nos queda esto

<project>
   <properties>
      <proyecto1.version>2.1-SNAPSHOT</proyecto.version>
      <proyecto2.version>3.4</proyecto.version>
   </properties>
   <groupId>com.chuidiang</groupId>
   <artifactId>miproyecto</artifactId>
   <version>1.1-SNAPSHOT</version>
   <dependencies>
      <dependency>
         ….
         <version>${proyecto1.version}

 

Hay un detalle importante a tener en cuenta. Al pom.xml padre le hemos puesto una versión. Si a los pom.xml de los subproyectos NO les ponemos versión, heredan la del padre. De esta forma, cuando queremos cambiar una versión, vamos al pom.xml padre y cambiamos el número de versión, cambiando así automáticamente para todos los subproyectos. Luego hay que ir a los otros tres o cuatro proyectos gordos y en el pom.xml padre cambiamos la <property> correspondiente.

¿Cual es la pega? Que todos los subproyectos de un proyecto, en su tag <parent>, llevan la versión del padre puesta "a pelo". Hay que recorrer todos los subproyectos buscando esa <version> de <parent> y cambiarla.  Aquí es donde entra el maven-versions-plugin. Aparte de un montón de opciones interesantes para analizar y cambiar versiones en los pom.xml, el comando

mvn versions:update-child-modules

cambia la versión de <parent> de todos los submodulos para que coincida con la del padre. Es decir, nos basta cambiar la versión del pom.xml raíz y luego ejecutar este comando para actualizar todos los submodulos.

Y aunque no es lo mejor, ya que no tenemos una versión independiente para cada jar, al menos nos permite versionar nuestros jar de forma sencilla.

Aprovecho para comentar algunos comandos útiles de este maven-versions-plugin.

  • mvn versions:display-*-updates muestra un listado de aquellos jar de los que dependemos que tienen versiones más modernas disponibles.
  • mvn versions:use-next-* modifica los pom.xml para que usemos la siguiente version disponible de los jar en los que no estamos usando la última disponible.
  • mvn versions:use-latest-* idem al anterior, pero nos pone la última versión disponible.
  • mvn version:lock-snapshot cambia todos los -SNAPSHOT por una -FechaHoraConcreta. Esto es muy útil para hacer "semi congelaciones" de código. Si tu proyecto va a pasar una prueba no muy importante (digamos una demo) y no quieres que te afecten cambios que otros estén haciendo en las librerías comunes, usas este comando y así tienes "congeladas" las librerías comunes hasta que pase tu demo.

En fin, un plugin que aunque todavía no he usado mucho, promete ser interesante.

 

 

Entradas relacionadas:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.