tools - Obteniendo la versión de Maven en Jenkins
jenkinsfile maven example (10)
¿Hay alguna forma en que una versión de Jenkins conozca el número de versión de Maven de un proyecto después de procesar el POM?
Tengo algunos proyectos en los que el control de versiones está controlado por Maven, y en un trabajo posterior a la creación nos gustaría crear un paquete Debian y llamar a algunos scripts de shell. Lo que necesito es el número de versión que Maven solía estar disponible como una variable de entorno de Jenkins para poder pasarlo a las acciones posteriores a la compilación.
Para ser claro, no necesito saber cómo conseguir que Jenkins le pase un número de versión a Maven; en cambio, ¡quiero que Maven le pase un número de versión a Jenkins!
Como ya se señaló en otras respuestas, si está utilizando el tipo de proyecto Maven, tiene acceso a la variable $ POM_VERSION . Pero si no lo está, puede usar esta secuencia de pasos (fea pero confiable). Hacerlo de esta manera depende de la misma versión de maven para determinar la versión de pom (mientras se maneja la herencia de pom padre / hijo compleja donde <version> puede no estar presente para el niño).
Maven paso con este objetivo:
org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version -l version.log
Paso de shell : (Es posible que deba ajustar la ruta a version.log dependiendo de su jerarquía)
echo "POM_VERSION=$(grep -v ''/['' version.log)" > props.properties
Paso Inyectar variables de entorno (complemento de inyector de entorno):
Ruta del archivo de propiedades:
props.properties
Ahora puede usar $ POM_VERSION como si fuera un proyecto de Maven.
Lo que hace: Utiliza maven para imprimir la versión junto con un lío de salida, luego elimina el lío de salida dejando solo la versión, lo escribe en un archivo usando el formato de archivo de propiedades y luego lo inyecta en el entorno de compilación. La razón por la cual esto es mejor que un one-liner como mvn ..... | grep -v ''/[''
mvn ..... | grep -v ''/[''
es que el uso de un paso Maven no hace suposiciones sobre las versiones maven instaladas y será manejado por la misma autoinstalación que cualquier otro paso de maven.
Después de investigar mucho (¡Nunca me había dado cuenta de lo poco documentado que es Jenkins!) Encontré una solución bastante trivial.
- Instala el plugin Groovy
- Agregue un
Post Step
a su compilación Maven de tipoExecute **system** Groovy script
- Pegue en el siguiente fragmento de Groovy:
Guión:
import hudson.model.*;
import hudson.util.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def mavenVer = currentBuild.getParent().getModules().toArray()[0].getVersion();
def newParamAction = new hudson.model.ParametersAction(new hudson.model.StringParameterValue("MAVEN_VERSION", mavenVer));
currentBuild.addAction(newParamAction);
La variable de entorno de compilación llamada MAVEN_VERSION
ahora estará disponible para su sustitución en otros pasos posteriores a la compilación de la manera habitual ( ${MAVEN_VERSION}
). Lo estoy usando para etiquetar a Git, entre otras cosas.
Ejecutar el complemento Maven "exec-maven-plugin" en "Ejecutar Shell" como un "Paso condicional" funcionó para mí:
mvn -q -Dexec.executable="echo" -Dexec.args=''${projects.version}'' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec
Integrar en Jenkins:
-> "Add post-build step"
-> "Conditional steps (single or multiple)"
-> "Execute Shell:"
exportar MY_POM_VERSION = `mvn -q -Dexec.executable =" echo "-Dexec.args = ''$ {projects.version}'' --no recursivo org.codehaus.mojo: exec-maven-plugin: 1.3.1: exec `&& [[" $ {MY_POM_VERSION} "==" THE_VERSION_TO_BE_MATCHED "]] && echo" CONDITION_IS_MET "
-> "Steps to run if condition is met"
-> Add any build step you need
Notas:
- THE_VERSION_TO_BE_MATCHED tiene que intercambiarse con su versión
- ''&& echo "CONDITION_IS_MET"'' solo tiene fines de depuración. Con el mismo propósito, puede agregar un "&& echo" MY_POM_VERSION = $ {MY_POM_VERSION} "''después del comando mvn para comprender lo que está sucediendo.
Este enfoque es más confiable que un "grep" y podría ser una alternativa si el Jenkins Ruby Plugin no está instalado.
Puede usar la variable $ {POM_VERSION}, que se introdujo con https://issues.jenkins-ci.org/browse/JENKINS-18272
También podrías hacer:
MAVEN_VERSION=`grep A -2 -B 2 "<your_project_name>" pom.xml | grep version | cut -d/> -f 2 | cut -d/< -f 1`-commit-"`echo $GIT_COMMIT`"
Explicación: suponiendo que tiene su nombre de proyecto dentro de una línea o dos arriba / abajo de la versión como un pom normal:
<groupId>org.apache.bigtop</groupId>
<artifactId>bigpetstore</artifactId>
<version>1.0-SNAPSHOT</version>
Luego puedes grep fácilmente para el artifactId, usar las acciones grep "antes / después" para absorber la versión con él, y luego grep la versión y usar el simple comando "cortar" de unix para empalmar el contenido entre "versión" etiquetas.
Me gusta la integración de Jenkins-groovy, pero esto es mucho más fácil y funcionará incluso en un servidor de compilación sobre el que no tienes control (es decir, porque bash es universal).
Tenía la misma necesidad y la resolvió como se sugirió con Groovy analizando el pom.
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def workspace = currentBuild.getModuleRoot().absolutize().toString();
def project = new XmlSlurper().parse(new File("$workspace/pom.xml"))
def param = new hudson.model.StringParameterValue("project.version", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
Agregue este script como un paso posterior al tipo "Ejecutar script de Groovy del sistema" (por lo que no es necesario instalar Groovy) y pegue el código en el "comando Groovy".
Usamos el complemento Groovy Postbuild .
String regex = ''.*//[INFO//] Building .+ (.+)'';
def matcher = manager.getLogMatcher(regex);
if (matcher == null) {
version = null;
} else {
version = matcher.group(1);
}
Agregar esto a Jenkins para su posterior uso es un poco complicado. Dale una oportunidad, aunque recuerdo que esto nos causa algunos dolores de cabeza. (Lo siento, hicimos esto hace mucho tiempo)
def addBuildParameter(String key, String value) {
manager.build.addAction(new hudson.model.ParametersAction(new hudson.model.StringParameterValue(key,value)));
}
Usando ''Execute System Groovy Script'' de la siguiente manera:
import jenkins.util.*;
import jenkins.model.*;
def thr = Thread.currentThread();
def currentBuild = thr?.executable;
def projectManager = build.getProject()
def file = projectManager.getWorkspace().child("pom.xml");
def project = new XmlSlurper().parseText(file.readToString())
def param = new hudson.model.StringParameterValue("currentVersion", project.version.toString())
currentBuild.addAction(new hudson.model.ParametersAction(param));
Al utilizar el script Execute System Groovy tiene acceso directo a la compilación, desde donde puede obtener el proyecto y, por lo tanto, el archivo "secundario" en este caso pom.xml.
No tendrá que crear un nuevo archivo y, como puede ver, ofrece un acceso muy potente a cada archivo dentro del espacio de trabajo.
Utilicé el plugin Pipeline Utility Steps en un trabajo de canalización declarativa para obtener la versión de Maven. En el siguiente ejemplo, utilizo la variable de secuencia de comandos en lugar de la variable de entorno, porque eso se puede modificar y pasar entre las etapas.
def TAG_SELECTOR = "UNINTIALIZED"
pipeline {
agent any
stages {
stage(''Build'') {
steps {
sh "mvn --batch-mode -U deploy"
script {
TAG_SELECTOR = readMavenPom().getVersion()
}
echo("TAG_SELECTOR=${TAG_SELECTOR}")
}
}
}
}
Nota: Debe aprobar el método getVersion () después de crear el trabajo en Gestionar jenkins > Aprobación del script en proceso .
Ver también:
Solución:
POM_VERSION=$( /
xmlstarlet sel /
-N x=''http://maven.apache.org/POM/4.0.0'' /
-t /
-v ''//x:project/x:version/text()'' /
pom.xml /
)
Explicación:
Puede hacer esto en un único trazador utilizando una herramienta XPath de línea de comandos, como las mencionadas en " ¿Cómo ejecutar XPath líneas simples desde el shell? ". Elegí XMLStarlet , pero todos tienen una sintaxis similar.
Al analizar un POM, debe contabilizar los espacios de nombres. Los documentos here me ayudaron a resolver esto.
Para obtener el texto de un elemento en XPath, use la función de texto () como se explica en XPath: seleccione el nodo de texto .
Mi POM se ve así:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.6-SNAPSHOT</version>
<packaging>jar</packaging>
La desventaja aquí es que si el espacio de nombres cambia, debe cambiar el comando.