IntelliJ IDEA tiene hoy el analizador de código Java estático más avanzado, que en sus capacidades dejó muy atrás a "veteranos" como Checkstyle y Spotbugs . Sus numerosas "inspecciones" verifican el código en varios aspectos, desde el estilo de codificación hasta los errores característicos.
Sin embargo, aunque los resultados del análisis se muestran solo en la interfaz local del IDE del desarrollador, son de poca utilidad para el proceso de desarrollo. El análisis estático debe realizarse como el primer paso de la tubería de ensamblaje, sus resultados deben determinar las compuertas de calidad y el ensamblaje debe fallar si no se pasan las compuertas de calidad. Se sabe que TeamCity CI está integrado con IDEA. Pero incluso si no está utilizando TeamCity, puede intentar ejecutar inspecciones IDEA en cualquier otro servidor CI. Propongo ver cómo se puede hacer esto usando el complemento IDEA Community Edition, Jenkins y Warnings NG.
Paso 1. Ejecute el análisis en el contenedor y obtenga un informe
Inicialmente, la idea de iniciar un IDE (aplicación de escritorio) dentro de un sistema de CI que no tiene una interfaz gráfica puede parecer dudosa y muy problemática. Afortunadamente, los desarrolladores de IDEA han proporcionado la capacidad de ejecutar el formato de código y las inspecciones desde la línea de comandos. Además, para ejecutar IDEA en este modo, no se requiere un subsistema gráfico y estas tareas se pueden realizar en servidores con un shell de texto.
Las inspecciones se bin/inspect.sh
utilizando el bin/inspect.sh
del directorio de instalación de IDEA. Como se requieren parámetros:
- ruta completa al proyecto (relativo no compatible)
- ruta al archivo .xml con la configuración de inspección (generalmente ubicada dentro del proyecto en .idea / inspectionProfiles / Project_Default.xml),
- ruta completa a la carpeta en la que se agregarán los archivos .xml con informes sobre los resultados del análisis.
Además, se espera que
- el IDE configurará la ruta al SDK de Java; de lo contrario, el análisis no funcionará. Estas configuraciones están contenidas en el archivo de configuración
jdk.table.xml
en la carpeta de configuración global IDEA. La configuración IDEA global en sí se encuentra por defecto en el directorio de inicio del usuario, pero esta ubicación se puede especificar explícitamente en el archivo idea.properties
. - el proyecto analizado debe ser un proyecto IDEA válido, para el cual el control de versiones tendrá que confirmar algunos archivos que generalmente se ignoran, a saber:
.idea/inspectionProfiles/Project_Default.xml
: configuración del analizador, obviamente se utilizarán al iniciar las inspecciones en el contenedor,.idea/modules.xml
: de lo contrario, .idea/modules.xml
el error 'Este proyecto no contiene módulos',.idea/misc.xml
: de lo contrario, .idea/misc.xml
el error 'El JDK no está configurado correctamente para este proyecto',*.iml-
: de lo contrario, *.iml-
un error sobre un JDK no configurado en el módulo.
Aunque estos archivos generalmente se incluyen en .gitignore
, no contienen ninguna información específica del entorno de un desarrollador en particular, a diferencia, por ejemplo, del archivo workspace.xml
, donde se encuentra dicha información y, por lo tanto, no es necesario confirmarla.
En sí mismo, pide una forma de empaquetar el JDK junto con IDEA Community Edition en un contenedor en una forma lista para "configurar" los proyectos analizados. Seleccionaremos el contenedor base apropiado, y aquí está el Dockerfile que obtenemos:
Dockerfile FROM openkbs/ubuntu-bionic-jdk-mvn-py3 ARG INTELLIJ_VERSION="ideaIC-2019.1.1" ARG INTELLIJ_IDE_TAR=${INTELLIJ_VERSION}.tar.gz ENV IDEA_PROJECT_DIR="/var/project" WORKDIR /opt COPY jdk.table.xml /etc/idea/config/options/ RUN wget https://download-cf.jetbrains.com/idea/${INTELLIJ_IDE_TAR} && \ tar xzf ${INTELLIJ_IDE_TAR} && \ tar tzf ${INTELLIJ_IDE_TAR} | head -1 | sed -e 's/\/.*//' | xargs -I{} ln -s {} idea && \ rm ${INTELLIJ_IDE_TAR} && \ echo idea.config.path=/etc/idea/config >> idea/bin/idea.properties && \ chmod -R 777 /etc/idea CMD idea/bin/inspect.sh ${IDEA_PROJECT_DIR} ${IDEA_PROJECT_DIR}/.idea/inspectionProfiles/Project_Default.xml ${IDEA_PROJECT_DIR}/target/idea_inspections -v2
Usando la opción idea.config.path
a IDEA a buscar su configuración global en la carpeta /etc/idea
, porque la carpeta de inicio del usuario en condiciones de CI es algo indefinido y a menudo completamente ausente.
Así es como se jdk.table.xml
archivo jdk.table.xml
copiado en el contenedor, en el que se escriben las rutas al OpenJDK instalado dentro del contenedor (se puede tomar un archivo similar desde su propio directorio con la configuración de IDEA):
jdk.table.xml <application> <component name="ProjectJdkTable"> <jdk version="2"> <name value="1.8" /> <type value="JavaSDK" /> <version value="1.8" /> <homePath value="/usr/java" /> <roots> <annotationsPath> <root type="composite"> <root url="jar://$APPLICATION_HOME_DIR$/lib/jdkAnnotations.jar!/" type="simple" /> </root> </annotationsPath> <classPath> <root type="composite"> <root url="jar:///usr/java/jre/lib/charsets.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/deploy.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/access-bridge-64.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/cldrdata.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/dnsns.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/jaccess.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/jfxrt.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/localedata.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/nashorn.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunec.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunjce_provider.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunmscapi.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunpkcs11.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/zipfs.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/javaws.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jce.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jfr.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jfxswt.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jsse.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/management-agent.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/plugin.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/resources.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/rt.jar!/" type="simple" /> </root> </classPath> </roots> <additional /> </jdk> </component> </application>
La imagen final está disponible en Docker Hub .
Antes de continuar, verifique el inicio del analizador IDEA en el contenedor:
docker run --rm -v <///>:/var/project inponomarev/intellij-idea-analyzer
El análisis debería funcionar con éxito, y numerosos archivos .xml con informes del analizador deberían aparecer en la subcarpeta target / idea_inspections.
Ahora ya no hay ninguna duda de que IDEA se puede ejecutar sin conexión en cualquier entorno de CI, y pasamos al segundo paso.
Paso 2. Visualizar y analizar el informe.
Obtener un informe en forma de archivos .xml es la mitad de la batalla, ahora debe hacerlo legible para los humanos. Y también sus resultados deben usarse en puertas de calidad: la lógica de determinar si un cambio aceptado se aprueba o no de acuerdo con los criterios de calidad.
Esto nos ayudará a Jenkins Warnings NG Plugin , que se lanzó en enero de 2019. Con su aparición, muchos complementos individuales para trabajar con los resultados del análisis estático en Jenkins (CheckStyle, FindBugs, PMD, etc.) ahora están marcados como obsoletos.
El complemento consta de dos partes:
- numerosos recopiladores de mensajes del analizador (la lista completa incluye todos los analizadores conocidos, desde AcuCobol hasta ZPT Lint),
- un solo espectador para todos ellos.
La lista de lo que Warnings NG puede analizar incluye advertencias del compilador de Java y advertencias de los registros de tiempo de ejecución de Maven: aunque están constantemente a la vista, rara vez se analizan a propósito. Los informes IntelliJ IDEA también se incluyen en la lista de formatos reconocidos.
Dado que el complemento es nuevo, inicialmente interactúa bien con Jenkins Pipeline. El paso de ensamblaje con su participación se verá así (solo le decimos al complemento qué formato de informe reconocemos y qué archivos deben analizarse):
stage ('Static analysis'){ sh 'rm -rf target/idea_inspections' docker.image('inponomarev/intellij-idea-analyzer').inside { sh '/opt/idea/bin/inspect.sh $WORKSPACE $WORKSPACE/.idea/inspectionProfiles/Project_Default.xml $WORKSPACE/target/idea_inspections -v2' } recordIssues( tools: [ideaInspection(pattern: 'target/idea_inspections/*.xml')] ) }
La interfaz del informe se ve así:

Convenientemente, esta interfaz es universal para todos los analizadores reconocidos. Contiene un diagrama interactivo de la distribución de hallazgos por categoría y un gráfico de la dinámica de los cambios en el número de hallazgos. En la cuadrícula en la parte inferior de la página, puede realizar una búsqueda rápida. Lo único que IDEA no funcionó para la inspección fue la capacidad de explorar el código directamente en Jenkins (aunque para otros informes, por ejemplo, Checkstyle, este complemento puede hacerlo de maravilla). Esto parece ser un error del analizador de informe IDEA para corregir.
Entre las capacidades de Warnings NG está la capacidad de agregar hallazgos de diferentes fuentes en un informe y programar Quality Gates, incluido un trinquete para el ensamblaje de referencia. Aquí hay disponible documentación de programación de Quality Gates; sin embargo, no está completa y debe consultar la fuente. Por otro lado, para un control total sobre lo que está sucediendo, el "trinquete" se puede implementar de forma independiente (vea mi publicación anterior sobre este tema).
Conclusión
Antes de comenzar a preparar este material, decidí buscar: ¿alguien ya escribió sobre este tema en Habré? Solo encontré una entrevista de 2017 con Lany donde dice:
Hasta donde yo sé, no hay integración con Jenkins o el complemento Maven [...] En principio, cualquier entusiasta podría hacer amigos IDEA Community Edition y Jenkins, muchos se beneficiarían de esto.
Bueno: dos años después, tenemos Warnings NG Plugin, ¡y finalmente esta amistad se ha hecho realidad!