Executa as inspeccións IntelliJ IDEA en Jenkins

IntelliJ IDEA ten hoxe o analizador de código Java estático máis avanzado, que, en canto ás súas capacidades, deixou atrás a tales "veteranos" como Estilo de verificación и Spotbugs. As súas numerosas "inspeccións" verifican o código en varios aspectos, desde o estilo de codificación ata os erros característicos.

Non obstante, sempre que os resultados da análise se mostren só no IDE local do programador, de pouco serven para o proceso de desenvolvemento. Análise estática debe levarse a cabo como primeiro paso do pipeline de construción, os seus resultados deben determinar as portas de calidade, e a construción debe fallar se fallan as portas de calidade. Sábese que TeamCity CI está integrado con IDEA. Pero aínda que non esteas a usar TeamCity, aínda podes probar a executar inspeccións IDEA en calquera outro servidor CI. Propoño ver como se pode facer isto usando o complemento IDEA Community Edition, Jenkins e Warnings NG.

Paso 1. Executa a análise nun contedor e obtén un informe

Ao principio, a idea de executar un IDE (aplicación de escritorio!) dentro dun sistema CI que non teña unha interface gráfica pode parecer dubidosa e moi problemática. Afortunadamente, os desenvolvedores de IDEA proporcionaron a posibilidade de executarse formato de código и inspeccións desde a liña de comandos. Ademais, para executar IDEA neste modo, non é necesario un subsistema gráfico, e estas tarefas pódense realizar en servidores cun shell de texto.

As inspeccións lánzanse mediante un script bin/inspect.sh dende o directorio de instalación de IDEA. Os parámetros necesarios son:

  • camiño completo ao proxecto (non se admiten os relativos),
  • ruta ao ficheiro .xml coa configuración de inspección (normalmente situada dentro do proxecto en .idea/inspectionProfiles/Project_Default.xml),
  • ruta completa ao cartafol onde se almacenarán os ficheiros .xml cos informes de resultados da análise.

Ademais, espérase que

  • a ruta ao SDK de Java configurarase no IDE, se non, a análise non funcionará. Estas opcións están contidas no ficheiro de configuración. jdk.table.xml no cartafol de configuración global de IDEA. A propia configuración global de IDEA predeterminada está no directorio de inicio do usuario, pero nesta localización pódese establecer explícitamente en arquivo idea.properties.
  • o proxecto analizado debe ser un proxecto IDEA válido, para o que algúns ficheiros que normalmente se ignoran terán que estar comprometidos co control de versións, a saber:
    • .idea/inspectionProfiles/Project_Default.xml — axustes do analizador, obviamente utilizaranse cando se realicen inspeccións no contedor,
    • .idea/modules.xml - se non, aparece o erro 'Este proxecto non contén módulos',
    • .idea/misc.xml - se non, aparece o erro "O JDK non está configurado correctamente para este proxecto",
    • *.iml-файлы - se non, obteremos un erro sobre un JDK non configurado no módulo.

Aínda que estes ficheiros adoitan incluírse en .gitignore, non conteñen ningunha información específica do entorno dun programador en particular, a diferenza de, por exemplo, un ficheiro workspace.xml, onde dita información, xusta, está contida, e polo tanto non é necesario cometela.

Por si só, a saída suxire empaquetar o JDK xunto con IDEA Community Edition nun contedor nun formulario preparado para ser "configurado" nos proxectos analizados. Elixamos un contedor base axeitado e aquí está o Dockerfile que obtemos:

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 a opción idea.config.path fixemos que IDEA buscara a súa configuración global no cartafol /etc/idea, xa que o cartafol de inicio do usuario nas condicións de traballo en CI é cousa indefinida e moitas veces completamente ausente.

Así se ve o ficheiro copiado no contedor jdk.table.xml, que contén as rutas ao OpenJDK instalado dentro do contedor (pode estar baseado nun ficheiro similar do teu propio directorio de 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>

Imaxe rematada dispoñible en Docker Hub.

Antes de continuar, imos probar a executar o analizador IDEA no contedor:

docker run --rm -v <путь/к/вашему/проекту>:/var/project inponomarev/intellij-idea-analyzer

A análise debería funcionar correctamente e deberían aparecer numerosos ficheiros .xml con informes do analizador no subcartafol target/idea_inspections.

Agora non hai dúbida de que o analizador IDEA pode executarse en modo autónomo en calquera ambiente CI, e pasamos ao segundo paso.

Paso 2. Mostra e analiza o informe

Obter un informe en forma de ficheiros .xml é a metade da batalla, agora ten que ser lexible para os humanos. E tamén os seus resultados deberían usarse nas portas de calidade: a lóxica para determinar se o cambio aceptado pasa ou non segundo criterios de calidade.

Isto axudaranos Complemento NG de advertencias de Jenkinsque foi lanzado en xaneiro de 2019. Coa súa introdución, moitos complementos separados para traballar cos resultados da análise estática en Jenkins (CheckStyle, FindBugs, PMD, etc.) agora están marcados como obsoletos.

O complemento consta de dúas partes:

  • numerosos colectores de mensaxes do analizador (completa inclúe todos os analizadores coñecidos pola ciencia desde AcuCobol ata ZPT Lint),
  • un único visor de informes para todos eles.

A lista de cousas que Warnings NG pode analizar inclúe avisos do compilador Java e avisos dos rexistros de execución de Maven: aínda que están constantemente á vista, raramente se analizan a propósito. Os informes IntelliJ IDEA tamén se inclúen na lista de formatos recoñecidos.

Dado que o complemento é novo, inicialmente interactúa ben co Jenkins Pipeline. O paso de compilación coa súa participación terá o seguinte aspecto (só indicamos ao complemento que formato de informe recoñecemos e que ficheiros se deben escanear):

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')]
    )
}

A interface do informe ten o seguinte aspecto:

Executa as inspeccións IntelliJ IDEA en Jenkins

É conveniente que esta interface sexa universal para todos os analizadores recoñecibles. Contén un gráfico interactivo da distribución dos achados por categorías e un gráfico da dinámica dos cambios no número de achados. Na grella na parte inferior da páxina, pode realizar unha busca rápida. O único que non funcionou correctamente para as inspeccións de IDEA foi a posibilidade de buscar o código directamente en Jenkins (aínda que para outros informes, como Checkstyle, este complemento pode facelo moi ben). Parece ser un erro no analizador de informes IDEA que hai que corrixir.

Entre as características de Warnings NG está a capacidade de agregar achados de diferentes fontes nun informe e programa Quality Gates, incluíndo un trinquete para un conxunto de referencia. Algunha documentación de programación de Quality Gates está dispoñible aquí - porén, non está completo, e hai que mirar a fonte. Por outra banda, para un control total sobre o que está a suceder, o "trinquete" pódese implementar de forma independente (ver o meu publicación anterior sobre este tema).

Conclusión

Antes de comezar a preparar este material, decidín mirar: xa alguén escribiu sobre este tema en Habré? Só atopei entrevista 2017 с Lanyonde di:

Polo que sei, non hai integración con Jenkins ou un complemento experto [...] En principio, calquera entusiasta podería facer amigos de IDEA Community Edition e Jenkins, moitos só se beneficiarían diso.

Pois despois de dous anos temos o complemento Warnings NG, e por fin esta amizade fíxose realidade!

Fonte: www.habr.com

Engadir un comentario