¿Cuál es la forma Maven para las versiones de proyecto automáticas cuando se realiza entrega continua?


Tengo una aplicación web donde implementamos en producción cada vez que una característica está lista, a veces puede ser un par de veces al día, a veces puede ser un par de semanas entre versiones.

Actualmente, no incrementamos nuestros números de versión para nuestro proyecto, y todo ha estado sentado en la versión 0.0.1-SNAPSHOT durante más de un año. Me pregunto cuál es la forma Maven para hacer entrega continua para una web apps. Parece exagerado aumentar el número de versión en cada confirmación, y nunca golpear el número de versión como lo estamos haciendo ahora, también parece mal.

¿Cuál es la mejor práctica recomendada para este tipo de uso Maven?

El problema es en realidad doble:

  • Avance del número de versión del proyecto en un archivo pom.xml individual (y puede haber muchos).
  • Actualizando el número de versión en todos los componentes dependientes para usar los más recientes entre sí.
Author: uvsmtid, 2013-08-27

7 answers

Recomiendo la siguiente presentación que discute las realidades prácticas de hacer entrega continua con Maven:

La conclusión clave es que cada compilación es una versión potencial, así que no uses instantáneas.

 35
Author: Mark O'Connor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-06 16:15:24

Este es mi resumen basado en el video enlazado por la respuesta de Mark O'Connor.

  • La solución requiere un DVCS como git y un servidor CI como Jenkins.
  • No use compilaciones de instantáneas en la canalización de entrega Continua y no use el complemento maven release.
  • Las versiones instantáneas como 1.0-SNAPSHOT se convierten en versiones reales como 1.0.buildNumber donde buildNumber es el número de trabajo de Jenkins.

Pasos del algoritmo:

  1. Jenkins clona el repositorio git con el código fuente, y decir que el código fuente tiene la versión 1.0-SNAPSHOT
  2. Jenkins crea una rama de git llamada 1.0.JENKINS-JOB-NUMBER para que la versión instantánea se convierta en una versión real 1.0.124
  3. Jenkins invoca el plugin maven versions para cambiar el número de versión en el pom.archivos xml de 1.0-SNAPSHOT a 1.0.JENKINS-JOB-NUMBER
  4. Jenkins invoca mvn install
  5. Si el mvn install es un éxito, entonces Jenkins confirmará la rama 1.0.JENKINS-JOB-NUMBER y se creará una versión real que no sea instantánea con una etiqueta adecuada en git para reproducir más tarde. Si el mvn install falla entonces Jenkins simplemente eliminará la rama recién creada y fallará la compilación.

Recomiendo encarecidamente el video enlazado desde la respuesta de Mark.

 31
Author: ams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-19 03:15:29

A partir de Maven 3.2.1 las versiones compatibles con la entrega continua son compatibles desde el primer momento: https://issues.apache.org/jira/browse/MNG-5576 Puede utilizar 3 variables predefinidas en la versión:

${changelist}
${revision}
${sha1}

Así que lo que básicamente haces es:

  1. Establezca su versión en, por ejemplo, 1.0.0-${revision}. (Puede usar mvn versions:set para hacerlo rápida y correctamente en un proyecto de módulos múltiples.)
  2. Poner una propiedad <revision>SNAPSHOT</revision> para el desarrollo local.
  3. En su entorno de CI ejecute mvn clean install -Drevision=${BUILD_NUMBER} o algo así o incluso mvn clean verify -Drevision=${BUILD_NUMBER}.

Puedes usar por ejemplo https://wiki.jenkins-ci.org/display/JENKINS/Version+Number + Plugin para generar números de compilación interesantes.

Una vez que descubras que la compilación es estable (por ejemplo, pasar pruebas de aceptación) puedes enviar la versión a Nexus u otro repositorio. Cualquier compilación inestable simplemente va a la basura.

 13
Author: Piotr Gwiazda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-22 12:55:04

Hay algunas grandes discusiones y propuestas sobre cómo lidiar con el número de versión de maven y la entrega continua (CD) (las agregaré después de mi parte de la respuesta).

Así que primero mi opinión sobre las versiones INSTANTÁNEAS. En maven, una INSTANTÁNEA muestra que está actualmente en desarrollo para la versión específica anterior al sufijo de LA INSTANTÁNEA. Debido a esto, herramientas como Nexus o el maven-release-plugin tienen un tratamiento especial para las INSTANTÁNEAS. Para Nexus se almacenan en un repositorio separado y se permite actualizar múltiples artefactos con la misma versión de lanzamiento INSTANTÁNEA. Por lo tanto, una INSTANTÁNEA puede cambiar sin que usted lo sepa (porque nunca incrementa ningún número en su pom). Debido a esto, no recomiendo usar dependencias de INSTANTÁNEAS en un proyecto, especialmente en un mundo de CD, ya que la compilación ya no es confiable.

SNAPSHOT como versión del proyecto sería un problema cuando su proyecto es utilizado por otros, debido a las razones anteriores.

Otro problema de La instantánea para mí es que ya no es realmente rastreable ni reproducible. Cuando veo una versión 0.0.1-SNAPSHOT en producción, necesito hacer algunas búsquedas para averiguar cuándo se compiló a partir de qué revisión se compiló. Cuando encuentro una versión de este software en un sistema de archivos, necesito echar un vistazo al pom.propiedades o archivo de MANIFIESTO para ver si esto es basura antigua o tal vez la última y mejor versión.

Para evitar el cambio manual del número de versión (especialmente cuando se construye múltiples compilaciones al día) permita que el servidor de compilación cambie el número por usted. Así que para el desarrollo me gustaría ir con un

<major>.<minor>-SNAPSHOT

Versión pero al compilar una nueva versión, el servidor de compilación podría reemplazar la INSTANTÁNEA con algo más único y rastreable.

Por ejemplo uno de estos:

<major>.<minor>-b<buildNumber>
<major>.<minor>-r<scmNumber>

Por lo tanto, el número mayor y menor se puede usar para problemas de marketing o simplemente para mostrar que se ha alcanzado un nuevo gran hito y se puede cambiar manualmente cuando lo desee. Y el número del edificio (número de su servidor de Integración Continua) o el scmNumber (Revisión de SUbversion o GIT) hacen que cada versión sea única y rastreable. Cuando se usa la revisión buildNumber o Subversion las versiones del proyecto son incluso clasificables (no con números GIT). Con el buildNumber o el scmNumber también es un poco fácil ver qué cambios hay en esta versión.

Otro ejemplo es el versionado de stackoverflow que usa

<year>.<month>.<day>.<buildNumber>

Y aquí los desaparecidos enlaces:

 8
Author: mszalbach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-12 10:02:20

¡NO HAGAS ESTO!

<Major>.<minor>-<build>

Te morderá en la parte trasera porque Maven trata cualquier cosa después de un guion como LÉXICO. Esto significa que la versión 1 será léxicamente superior a 10.

Esto es malo como si usted está pidiendo la última versión de algo en maven, entonces el punto anterior gana.

La solución es usar un punto decimal en lugar de un guion que preceda al número de compilación.

¡HAZ ESTO!

<Major>.<minor>.<build>

Está bien tener versiones de INSTANTÁNEAS localmente, pero como parte de una compilación, es mejor usar

mvn versions:set -DnewVersion=${major}.${minor}.${build.number}

Hay formas de derivar la versión mayor/menor del pom, por ejemplo, usando help:evaluate y canalizando a una variable de entorno antes de invocar versions:set. Esto es sucio, pero realmente me rascé la cabeza (y a otros en mi equipo) para hacerlo más simple, y (en ese momento) Maven no era lo suficientemente maduro para manejar esto. Creo que Maven 2.3.1 podría tener algo que ayude de alguna manera a esto, por lo que esta información ya no puede ser pertinente.

Está bien que un grupo de desarrolladores para liberar en el mismo major.versión menor - pero siempre es bueno tener en cuenta que los cambios menores no se rompen y los cambios de versión mayores tienen algún cambio de API de ruptura, o desaprobación de la funcionalidad/comportamiento.

Desde una perspectiva de Entrega Continua, cada compilación es potencialmente liberable, por lo tanto, cada registro debe crear una compilación.

 6
Author: user924272,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-29 21:05:32

Como punto de partida puede echar un vistazo a Maven: La Referencia completa. Versiones del Proyecto.

Entonces hay un buen post sobre la estrategia de versionado.

 2
Author: dmitri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-27 03:18:44

En mi trabajo para web apps actualmente usamos este patrón de versionado:

<jenkins build num>-<git-short-hash>

Ejemplo: 247-262e37b9.

Esto es bueno porque te da una versión que siempre es única y rastreable hasta la compilación de jenkins y la revisión de git que la produjo.

En Maven 3.2.1+ finalmente eliminaron las advertencias por usar una property{property} como versión, por lo que es realmente fácil construirlas. Simplemente cambie todos sus poms para usar <version>${revision}</version> y compile con -Drevision=whatever. El único el problema con eso es que en sus poms liberados la versión se quedará en ${revision} en el archivo pom real que puede causar todo tipo de problemas extraños. Para resolver esto escribí un plugin maven simple ( https://github.com/jeffskj/cd-versions-maven-plugin ) que hace el reemplazo de la variable en el archivo.

 1
Author: Jeff S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-28 00:03:26