Herramientas y Métodos en Ingeniería del Software. Version curso.2022. Joaquín Cañadas <jjcanada@ual.es>
Integración Continua con Jenkins.
-
Construcción automatizada de proyectos Java basados en Maven usando Jenkins como servidor de Integración Continua
-
Diseño de los pasos de construcción con Jenkins Pipelines
-
Configurar Webhooks para la integración de GitHub y Jenkins
-
Generación y visualización de los informes de evolución del proyecto
1. Introducción a la Integración Continua con Jenkins
Jenkins CI es un sistema de Integración Continua open source, desarrollado por Kohsuke Kawaguchi, desarrollador de la ex Sun Microsystems y posteriormente de Oracle. En 2010 fundó CloudBees, empresa que da soporte empresarial de Jenkins.
Jenkins proporciona integración continua en el desarrollo de software, es decir, permite configurar y agendar la ejecución de las tareas que componen toda y/o cada una de las partes que conforman el ciclo de vida de un proyecto. Para dar una idea de esto, basta pensar en los famosos night-builds, los cuales son compilaciones, validaciones y liberaciones de versiones beta que realizan algunos sistemas durante las noches de forma automática sobre lo que han ido trabajando los desarrolladores durante el día.
Jenkins nace como fork del sistema predecesor Hudson CI, del mismo autor, como alternativa open source desde que Sun fue adquirida por Oracle y cambiada su licencia.
Jenkins posee una interminable lista de plugins, los cuales le permiten definir tareas que pueden integrarse con herramientas de control de versiones (Subversion, Git, …), ejecutar proyectos basados en Apache Maven, Apache Ant, Microsoft MSBuild, shell y batch scripts, y muchas otras. Además permite ejecutar tareas adicionales previa y posteriormente a la construcción, como por ejemplo preparar el entorno, realizar un despliegue o compactar y subir binarios a un servidor por SSH.
Para cada proyecto, Jenkins guarda un historial de cambios realizados por build o versión, almacena quién lo realizo y cuales archivos fueron manipulados, y sus comentarios al respecto.
Existen otras muchas herramientas de integración continua y despliegue continuo (CI/CD), como Travis CI, Gitlab CI, Circle CI, Semaphore CI, Appveyor, Azure DevOps, y muchas más. |
1.1. Principales características
-
Automatiza la construcción del software, periódicamente o en base a unas condiciones. En proyectos Maven se puede simular una construcción similar a un equipo que sólo tuviese instalado Java y Maven (y el correspondiente sistema operativo); de este modo, se elimina el perverso efecto de la contaminación de los equipos de desarrollo.
-
Centraliza la información referida a la construcción del software y al estado y salud del proyecto:
-
Estado de la construcción.
-
Informes sobre la construcción.
-
Informes sobre las pruebas.
-
Site del proyecto.
-
-
Gestiona la interacción con otras herramientas, como por ejemplo [SonarQube](https://sonarcloud.io/), de mide de calidad del software.
1.2. ¿Por qué usarlo?
-
Simplifica significativamente (a un par de clicks y dentro de un entorno web lo que lo hace fácilmente accesible desde cualquier parte) los procesos involucrados en el ciclo de vida de un proyecto, ya sean simples o repetitivos, largos y complejos como puede ser de generación de binarios, integrando el trabajo de varios desarrolladores, ejecución de pruebas automatizadas, generación de informes, publicación en pagina web, notificación a clientes de versiones beta, etc.
-
Da un marco de simplicidad sobre la integración continua gracias a las diferentes posibilidades de notificaciones de éxitos y errores entre procesos, por lo que con la formación adecuada sobre los mismos se puede asegurar una altísima calidad de software desde el primer día, evitando errores, demoras y a un mínimo coste.
-
Debido a los múltiples sistemas de notificaciones por cual optar (ya sea por mail, chat, slack, twitter, etc), es sencillo estar siempre informado y poder tomar decisiones rápidamente.
Aquí pueden encontrar un resumen de beneficios y preocupaciones de Jenkins.
1.3. CI/CD y DevOps
La integración continua forma parte de un proceso más amplio conocido como entrega continua o despliegue continuo (Continuous Delivery, Continuous Deployment), que además abarca el despliegue automatizado de proyectos en distintos entornos de ejecución. Por ello, frecuentemente en la bibliografía se hace referencia como CI/CD, de sus siglas en inglés: Continuous Integration and Continuous Delivery.
CI/CD es una práctica fundamental dentro de la metodología DevOps en ingeniería del software.
2. Prerrequisitos
Para comenzar a trabajar en esta sesión, será necesario haber realizado las actividades anteriores de JUnit y Maven. Al menos, haberlas empezado, porque si aun no las has terminado, ¡¡¡no te preocupes!!! De hecho, es mejor que hagas esta actividad de Jenkins antes de terminar las anteriores de JUnit y Maven, ya que así verás como Jenkins visualiza los gráficos de evolución (tests, métricas, etc.) cuando vayas completando las actividades anteriores.
Además, se debe disponer de crédito en Azure, y es necesario disponer de una máquina virtual con Jenkins instalado y un usuario con permisos (todo ello realizado en sesiones anteriores). Igualmente, se dispone de usuario en GitHub y los repositorios git en GitHub de los proyectos Java de las sesiones anteriores. También, debes tener una pareja de claves SSH personal en la carpeta HOME
del usuario de tu equipo (~
).
~/.ssh/
├── id_rsa (1)
└── id_rsa.pub (2)
1 | clave privada |
2 | clave pública |
3. Instalación de plugins adicionales
En primer lugar, es recomendable actualizar Jenkins a la última versión, para evitar bugs y vulnerabilidades de seguridad que hayan sido arregladas en la última versión. Para ello, accede a tu máquina Jenkins por ssh y ejecuta la actualización de paquetes:
ssh ubuntu@dns.maquina.jenkins
sudo apt-get update -y sudo apt-get upgrade -y
A partir de marzo 2023 hay que actualizar las claves de firma de Jenkins
|
Tras la actualización y reinicio de Jenkins, vamos a instalar varios plugins adicionales en Jenkins, si aun no están instalados: Github integration, Maven Integration, Cobertura, Jacoco (comprobar antes si no están instalados ya), Code Coverage Api, JavaDoc, Warnings Next Generation, Embeddable Build Status Plugin, xUnit, Monitoring, etc.
Haz clic en Manage Jenkins > Manage Plugins. En la pestaña Available busca Github integration, seleccionalo y pulsa en Download now and install after restart.

Repite los pasos para los plugins Maven Integration, Cobertura, JavaDoc y xUnit.
Necesitaremos visualizar el resultado de la cobertura en Jenkins. Para ello instala el plugin de JaCoCo (Java Code Coverage) y el plugin Code Coverage API.


Para visualizar el resultado del análisis estático de código, necesitaremos el plugin Warnings Next Generation. Procede de la misma forma.
Instala además el Embeddable Build Status Plugin, que nos permitirá visualizar en el archivo README.md del proyecto, o en cualquier otro sitio, un pequeño badge o insignia con el estado de build del proyecto.

Instala además los plugins: Monitoning, Job Configuration History y Pipeline Configuration History, que nos permitiran, el primero, monitorizar el estado de Jenkins (uso de recursos, etc) para poder decidir si la máquina necesita ser dimensionada a una más grande (con más nucleos, RAM, etc), y los dos siguientes, guardar un historial de los cambios en la configuración de los proyectos y pipelines, por si falla la nueva configuración poder recuperar alguna versión anterior.
Por último, marca Restart Jenkins para completar la instalación. Tras unos segundos, vuelve a iniciar sesión y tendrás los plugins instalados.

El plugin Embeddable Build Status necesita dar acceso al usuario anónimo en la configuración de seguridad de Jenkins, para que se pueda leer el estado de construcción del proyecto: ![]() Fig. 6. Acceso al usuario anómimo
|
Además de los plugins, para que la máquina virtual de Jenkins funcione correctamente al aumentar la carga de trabajo, es necesario añadir memoria Swap (en disco), al menos 2 Gb. Aquí tienes los pasos: How To Add Swap Space on Ubuntu 18.04. Si tienes crédito de sobra en tu cuenta Azure, puedes incluso cambiar el tamaño de la máquina virtual para que tenga más cores y RAM. |
4. Tipos de proyectos en Jenkins
En Jenkins existen varios tipos de proyectos. Al hacer clic en nuevo elemento, aparece la vista de creación de nuevo proyecto, en la que debemos introducir el nombre del proyecto y su tipo. Los 3 principales tipos son:
-
Estilo libre (Freestyle project): es el más flexible en su configuración. Permite construir proyectos en cualquier tecnología, en función de las herramientas (tools) y plugins que tengas instalados. Se utiliza cuando deseemos ejecutar fundamentalmente comandos desde la shell. En la sesión de despliegue automatizado de la web del equipo (sesión 05) usamos proyectos de este tipo.
-
Proyecto Maven: se utiliza para construir proyectos Java basados en Maven. De forma predeterminada incluye un paso en el que añadir los goals de maven que se deseen ejecutar en la construcción del proyecto.
-
Pipeline: un pipeline o tubería identifica los pasos o fases (stages) que se van a ejecutar en el proceso de construcción del proyecto. Cada fase tiene definido cómo se ejecuta, y los resultados que produce. La ejecución de las fases es secuencial, aunque también se pueden configurar fases en paralelo.

En esta actividad vamos a construir en Jenkins un proyecto estilo libre en Ant, y los proyectos Java mavenizados de las sesiones anteriores de dos formas:
-
Utilizando la forma clásica, creando un proyecto tipo Maven.
-
Utilizando la descripción en pases mediante pipeline.
Comencemos por la primera forma.
5. Creación de un Proyecto con Ant
Comenzaremos con un ejemplo sencillo en Java denominado ConnectFour. Este proyecto se construye con Ant, y está disponible aquí: https://github.com/ualhmis/connect-four.git
Este ejercicio ConnectFour debe ser realizado individualmente por cada uno de los miembros del equipo. |
Si deseas hacer cambios, por ejemplo para corregir los tests que fallan, primero forkea el repositorio a tu cuenta de GitHub |
-
Creamos una nueva tarea de tipo estilo libre: el nombre debe ser connectFour-nombreMiembro

-
Jenkins conecta al repositorio donde están los fuentes para descargarlos. Selecciona Git, y añade esta URL: https://github.com/ualhmis/connect-four.git. Al tratarse de un repositorio público no necesita credenciales.

-
Archivo de construcción (build): en la ejecución de la tarea, elegimos Ant

-
Seleccionamos la versión de Ant instalada (no dejar “por defecto” porque da error), y en Destinos escribimos all

-
Acciones a ejecutar después: Publicamos los resultados de los test JUnit y la documentación JavaDoc

Y añadimos la ruta del archivo con los resultados de los test JUnit en xml: target/test-results/*.xml

-
Igualmente, añadimos otra acción a ejecutar después para JavaDoc

Y añadimos la ruta donde se han generado los archivos JavaDoc: target/docs

-
Guardamos
-
Construir ahora. Por consola se visualiza el resultado de la ejecución de las tareas Ant configuradas en el archivo
build.xml
del proyecto.
El resultado es bola amarilla, porque fallan un par de tests. Para ver una gráfica de resultados de los Test debemos ejecutar al menos 2 construcciones.

6. Creación de un Proyecto Maven
Para ese ejercicio, cada uno debe usar el repositorio de la práctica 7 donde se ha trabajado con Maven.
6.1. Construcción básica
-
Crea un nuevo proyecto Maven. El nombre debe ser ej07-maven-nombreMiembro.

-
Indica la URL del proyecto en Github. Utiliza aquí la URL de tu proyecto de la práctica 7.

-
Selecciona Git como control de código fuente. Indica la URL del repositorio.

En caso de que sea un repositorio privado tendrás que proporcionar unas credenciales. En Jenkins debes crear unas nuevas credenciales. Se recomienda crear en Jenkins unas credenciales de tipo Username and password, donde el password debe ser un token generado en GitHub. El token se genera en GitHub, sobre tu usuario: Settings, Developer Settings, Personal Access tokens, Generate New Token, y marcar las opciones de repo. Otra alternativa es crear en Jenkins unas credenciales tipo pareja de claves SSH, aunque es igual de mala práctica meter tu clave privada personal en Jenkins. Por ello, para esta alternativa, la buena práctica consiste en crear una nueva pareja de claves SSH exclusiva para que Jenkins pueda leer el repositorio privado, añadir la clave pública al repositorio en GitHub (exclusivamente al repositorio concreto, no a nuestro usuario de GitHub), y por último añadir la clave privada como credencial en Jenkins para que pueda leer ese repositorio privado de GitHub. |
-
En la sección de build, añade la ruta correcta al archivo
pom.xml
y por último añade los goals:clean package

-
Guarda los cambios
-
Construir ahora. Por consola se visualiza el resultado de la ejecución de maven.
En los proyectos Maven, no hace falta configurar la publicación de los test de JUnit, se hace de forma predeterminada a partir de la segunda construcción.

6.2. Webhook: construcción tras un push en GitHub
Mediante un Webhook se puede configurar que cuando el repositorio en GitHub reciba un push notificará a Jenkins para que lance la construcción automáticamente. Para ello, en la sección de disparadores de la construcción (build trigers) marca la opción de hook con Github:
6.3. Informe de cobertura
-
Añade los resultados de la cobertura obtenidos con JaCoCO: entra de nuevo en la configuración del proyecto, en post-build actions añade una acción a ejecutar después y selecciona Record JaCoCo coverage report

-
Configura la ruta correcta a los fuentes:
**/src/

-
Guarda los cambios y construye el proyecto. Al actualizar el proyecto verás la gráfica de Cobertura. Si ejecutas un par de builds la gráfica muestra la linea de evolución.

Y si haces clic en la gráfica, verás el informe detallado.

6.4. Añadiendo Javadoc y Site
-
Para generar la documentación en Javadoc y publicarla en la página del proyecto, simplemente añade los goals
javadoc:javadoc javadoc:aggregate
. -
Para generar la documentación Site de Maven y publicarla, simplemente añade el goal
site
.

-
Para poder visualizar correctamente el Site, hay que cambiar la configuración de seguridad de Jenkins predeterminada que es muy restrictiva para prevenir de archivos HTML/JS maliciosos. Para modificar la configuración, abre la consola de scritps (Manage Jenkins / Script Console), y ejecuta estas líneas para desestablecer la cabecera:
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")
System.getProperty("hudson.model.DirectoryBrowserSupport.CSP")

-
Tras ello ya podrás visualizar correctamente. Pero ten en cuenta que cada vez que reinicies Jenkins esta configuración se pierde y vuelve a la configuración predeterminada.
7. Creación de un Proyecto Pipeline
Para ese ejercicio, cada estudiante debe usar, de nuevo, el repositorio de la práctica 7 donde se ha trabajado con Maven. Vamos a configurar el proyecto Jenkins que construya el mismo repositorio de la sección anterior, pero esta vez vamos a utilizar pipelines.
7.1. Diseño del pipeline
-
Crea un nuevo proyecto y dale el nombre y selecciona tipo pipeline. El nombre debe ser ej07-pipeline-nombreMiembro.
-
Indica la URL del proyecto en Github. Utiliza aquí la URL de tu proyecto de la práctica 7.
-
En la sección Pipeline, disponemos de un cuadro de texto en el que añadir la descripción de nuestro pipeline utilizando la sintaxis declarativa que Jenkins proporciona. Vamos a ver cómo hacerlo.
pipeline {
agent any (1)
tools {
// Nombre dado a la instalación de Maven en "Global Tool configuration"
maven "Default Maven" (2)
}
stages { (3)
...
}
}
1 | agente o nodo de Jenkins en que ejecuta la construcción del proyecto. En el ejemplo, any indica que se ejecutará cualquier nodo, en nuestro caso será en master ya que es el único nodo que hay definido en nuestro Jenkins. |
2 | como herramienta para la construcción se usará maven. Pon aquí el nombre que diste a tu instalación de Maven configurada previamente en Tools Configuration. |
3 | Bloque de stages : fases o etapas que conforman el pipeline |
A continuación se muestra cómo definir cada fase o stage una a una dentro del bloque stages:
pipeline {
agent any
tools {
// Nombre dado a la instalación de Maven en "Tools configuration"
maven "Default Maven"
}
stages {
stage('Git fetch') { (1)
steps {
// Get some code from a GitHub repository
git branch: 'main', url: 'https://github.com/ualhmis/MavenEjercicios'
}
}
stage('Compile, Test, Package') { (2)
steps {
// When necessary, use '-f path-to/pom.xml' to give the path to pom.xml
// Run goal 'package'. It includes compile, test and package.
sh "mvn -f sesion07Maven/pom.xml clean package" (3)
}
post { (4)
// Record the test results and archive the jar file.
success {
junit '**/target/surefire-reports/TEST-*.xml'
archiveArtifacts '**/target/*.jar'
}
}
}
}
}
1 | El step git clona el repositorio git. En este ejemplo se trata de un repositorio público. También, puedes clonar un repo privado o una rama concreta usando los parámetros adecuados, por ejemplo: . Previamente has debido crear una credencial con el ID my-private-key-credential-id . Se recomienda usar credenciales de tipo Username and password, donde el password debe ser un token generado en GitHub. El token se genera en GitHub, sobre tu usuario: Settings, Developer Settings, Personal Access tokens, Generate New Token, y marcar las opciones de repo. Si necesitas hacer alguna otra parametrización, se recomienda usar el Snippet Generator. |
2 | Fase de build: compilación, test y empaquetado de la aplicación. |
3 | Se llama a maven con los goals clean package : elimina todo lo generado en la construcción anterior, y a continuación se lanza la construcción con package tal y como está definida en el archivo pom.xml . Cuando sea necesario, indique el path al archivo pom.xml con el parámetro -f path-to/pom.xml |
4 | Paso posterior al build, que guarda los resultados de los test de JUnit para generar la gráfica de evolución de los test. Además, archiva el empaquetado .jar para que pueda ser descargado posteriormente |

-
Guarda los cambios y construye.
-
Tras ejecutar el pipeline, con "Build now", el resultado debe ser el siguiente:

7.2. Informe de Cobertura de código
Para visualizar informe de cobertura en el pipeline, añade las dos siguientes linea al bloque post
:
...
success {
junit '**/target/surefire-reports/TEST-*.xml'
archiveArtifacts '**/target/*.jar'
jacoco( (1)
execPattern: '**/target/jacoco.exec',
classPattern: '**/target/classes',
sourcePattern: '**/src/',
exclusionPattern: '**/test/'
)
publishCoverage adapters: [jacocoAdapter('**/target/site/jacoco/jacoco.xml')] (2)
}
...
1 | Añade el informe Coverage Trend |
2 | Añade el informe Coverage Report |
Tras la construcción de nuevo del proyecto, verás la gráfica de los resultados de los test y debajo la gráfica de evolución de cobertura.

7.3. Análisis estático de código
Para mantener y aumentar la calidad de nuestro código debemos ayudarnos, entre otras herramientas, de técnicas de análisis estático de código. Básicamente, se encargan de buscar defectos en el código sin necesidad de que este se ejecute. En Java una de las más habituales es Checkstyle, aunque hay otras como FindBugs, PMD, y SonarQube que integra a los anteriores.
Para ejecutar y visualizar el análisis de Checkstyle, añade un nuevo stage al pipeline:
stage ('Analysis') {
steps {
// Warnings next generation plugin required
sh "mvn -f sesion07Maven/pom.xml checkstyle:checkstyle site -DgenerateReports=false"
}
post {
success {
recordIssues enabledForFailure: true, tool: checkStyle()
}
}
}
Tras la construcción, el pipeline tiene una nueva fase y además en el menú tenemos acceso al informe de CheckStyle.


Como parte del ejercicio, completa por ti mismo la publicación del resto de informes de análisis estático de código generados en la sesión 7. Se publican a través del plugin Warnings Next Generation.
-
PMD: añade el goal adecuado en la ejecución de maven y añade la publicación del informe:
recordIssues enabledForFailure: true, tool: pmdParser()
-
CPD: añade la publicación del informe:
recordIssues enabledForFailure: true, tool: cpd()
-
FingBugs: repite el proceso.
-
SpotBugs: repite el proceso.
El resultado final debe ser tal que así. Para que se ejecuten todos los análisis simplemente llamamos a site
ya que todos los tenemos definidos en el bloque <reporting>
del pom.xml
.
stage ('Analysis') {
steps {
// Warnings next generation plugin required
sh "mvn -f sesion07Maven/pom.xml site"
}
post {
success {
recordIssues enabledForFailure: true, tool: checkStyle()
recordIssues enabledForFailure: true, tool: pmdParser()
recordIssues enabledForFailure: true, tool: cpd()
recordIssues enabledForFailure: true, tool: findBugs()
recordIssues enabledForFailure: true, tool: spotBugs()
}
}
}
Como resultado debes ver las gráficas de cada una de estas 5 herramientas en la página del proyecto. Y haciendo clic en cada gráfica, así como en los enlaces del menú de la izquierda, se accede al detalle de cada informe.

7.4. Dependency-check
Dependency Check de OWASP (Open Web Application Security Project) es una herramienta que permite identificar las dependencias de nuestro proyecto y comprobar si hay alguna de ellas que tiene vulnerabilidades conocidas. En la práctica anterior configuramos el plugin dependency-check-maven
en el bloque <reporting>
del pom.xml
, por lo que este plugin se ejecuta cuando llamamos al goal site
. Puesto que ya hemos ejecutado site
en la fase anterior, no es necesario crear una nueva fase (stage) para generar el informe de Dependency-check, únicamente será necesario publicarlo en el pipeline.
-
Instala el plugin OWASP Dependency-Check en Jenkins.

-
Modifica el archivo
pom.xml
en tu proyecto y añade la siguiente línea para que genere el informe también en formato XML, que es el formato que lee el plugin:
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>5.3.2</version>
<configuration>
<skipTestScope>false</skipTestScope>
<formats> (1)
<format>HTML</format>
<format>XML</format>
</formats>
</configuration>
...
</plugin>
1 | Genera el informe en HTML y XML |
-
Añade en el pipeline la siguiente linea para publicar el informe, en el mismo bloque pero antes que checkstyle, pmd, etc.
dependencyCheckPublisher pattern: '**/target/site/dependency-check-report.xml'
-
Tras volver a construir el proyecto, aparecerá una nueva gráfica de Dependency Check en el proyecto. Si no tienes problemas de seguridad en las dependencias, esta gráfica estará en blanco. El enlace al informe de dependencias no aparece en la página principal del proyecto, en el menú de enlaces como el resto, sino que tienes que hacer clic en el número del último build, y en la nueva página ya aparece el enlace:

7.5. Documentación Javadoc y Site
La siguiente fase recomendada en el pipeline, de las lista de fases genéricas, es la de generar la documentación
Es necesario instalar previamente el plugin HTML Publisher de Jenkins.
Añade esta fase al pipeline:
stage ('Documentation') {
steps {
sh "mvn -f sesion07Maven/pom.xml javadoc:javadoc javadoc:aggregate" (1)
}
post{
success {
step $class: 'JavadocArchiver', javadocDir: 'sesion07Maven/target/site/apidocs', keepAll: false (2)
publishHTML(target: [reportName: 'Maven Site', reportDir: 'sesion07Maven/target/site', reportFiles: 'index.html', keepAll: false]) (3)
}
}
}
1 | Llamada a javadoc desde Maven. |
2 | Publica los archivos html de Javadoc y añade el enlace en el menú. |
3 | Publica el site y añade el enlace en el menú. |

7.6. Jenkinsfile
La descripción del pipeline puede guardarse en un archivo llamado Jenkinsfile
y guardarse en el repositorio como otro archivo de código más. Si haces esto, al configurar el proyecto en Jenkins debes elegir la opción Pipeline script from SCM en la sección de definición del pipeline. A continuación, debes proporcionar la URL del repositorio donde se encuentra el archivo Jenkinsfile.

8. FAQ y resolución de problemas (thoubleshouting)
En esta sección se añadirán soluciones a los problemas más habituales.
-
La construcción de maven funciona correctamente en Eclipse pero da error en Jenkins:
-
Revisa la versión de maven instalada en Jenkins, y actualiza a la última versión: En Jenkins / Manage Jenkins / Global Tool Configuration / Maven Installations. Selecciona la última versión disponible, marca install automatically, y dale un nombre por ejemplo
Default Maven
. IMPORTANTE: si tienes más de una instalación de maven, en los proyectos de tipo maven tendrás que elegir cual deseas usar a partir del nombre que le hayas dado a cada una de ellas, seleccionandola en una lista desplegable en la sección de build.
-
-
La fase de documentación del pipeline da error JAVA_HOME:
-
Si se muestra el error:
An error has occurred in Javadoc report generation: Unable to find javadoc command: The environment variable JAVA_HOME is not correctly set.
Debes añadir la variable de entornoJAVA_HOME
en la configuración de Jenkins: Jenkins > Manage Jenkins > Configure System > Global properties > Add environment variable. Añade la variableJAVA_HOME
con el valor de la ruta de instalación de Java, por ejemplo:/usr/lib/jvm/java-11-openjdk-amd64/
-