Esecuzione di ispezioni IntelliJ IDEA su Jenkins

IntelliJ IDEA oggi dispone dell'analizzatore di codice Java statico più avanzato, che nelle sue capacità lascia molto indietro i "veterani" come Stile di controllo и Spotbugs. Le sue numerose “ispezioni” controllano il codice sotto vari aspetti, dallo stile di codifica ai bug tipici.

Tuttavia, finché i risultati dell'analisi vengono visualizzati solo nell'interfaccia locale dell'IDE dello sviluppatore, sono di scarsa utilità per il processo di sviluppo. Analisi statica deve essere soddisfatto Come primo passaggio della pipeline di compilazione, i suoi risultati dovrebbero definire i limiti di qualità e la compilazione dovrebbe fallire se i limiti di qualità non vengono superati. È noto che TeamCity CI è integrato con IDEA. Ma anche se non utilizzi TeamCity, puoi facilmente provare a eseguire le ispezioni IDEA in qualsiasi altro server CI. Ti suggerisco di vedere come è possibile farlo utilizzando il plug-in IDEA Community Edition, Jenkins e Warnings NG.

Passaggio 1. Esegui l'analisi nel contenitore e ottieni un report

Inizialmente, l’idea di eseguire un IDE (applicazione desktop!) all’interno di un sistema CI che non dispone di un’interfaccia grafica può sembrare dubbia e molto problematica. Fortunatamente, gli sviluppatori di IDEA hanno fornito la possibilità di eseguirlo formattazione del codice и ispezioni dalla riga di comando. Inoltre, per eseguire IDEA in questa modalità, non è richiesto un sottosistema grafico e queste attività possono essere eseguite su server con una shell di testo.

Le ispezioni vengono avviate utilizzando uno script bin/inspect.sh dalla directory di installazione di IDEA. I parametri richiesti sono:

  • percorso completo del progetto (quelli relativi non sono supportati),
  • percorso del file .xml con le impostazioni di ispezione (solitamente situato all'interno del progetto in .idea/inspectionProfiles/Project_Default.xml),
  • percorso completo della cartella in cui verranno archiviati i file .xml con i report sui risultati dell'analisi.

Inoltre, è previsto che

  • il percorso dell'SDK Java verrà configurato nell'IDE, altrimenti l'analisi non funzionerà. Queste impostazioni sono contenute nel file di configurazione jdk.table.xml nella cartella di configurazione globale di IDEA. La stessa configurazione globale IDEA si trova nella directory home dell'utente per impostazione predefinita, ma questa posizione può essere specificato esplicitamente in archivio idea.properties.
  • Il progetto analizzato dovrà essere un progetto IDEA valido, per il quale dovrai committare alcuni file che solitamente vengono ignorati dal controllo versione, ovvero:
    • .idea/inspectionProfiles/Project_Default.xml — impostazioni dell'analizzatore, verranno ovviamente utilizzate durante l'esecuzione delle ispezioni nel contenitore,
    • .idea/modules.xml - altrimenti riceveremo l'errore "Questo progetto non contiene moduli",
    • .idea/misc.xml - altrimenti riceveremo l'errore "JDK non è configurato correttamente per questo progetto",
    • *.iml-файлы — altrimenti riceveremo un errore relativo a un JDK non configurato nel modulo.

Sebbene questi file siano solitamente inclusi in .gitignore, non contengono informazioni specifiche sull'ambiente di un particolare sviluppatore, a differenza, ad esempio, di un file workspace.xml, dove sono contenute tali informazioni, e pertanto non è necessario impegnarle.

La soluzione ovvia è impacchettare il JDK insieme a IDEA Community Edition in un contenitore in una forma pronta per essere “snocciolata” sui progetti analizzati. Scegliamo un contenitore base adatto, ed ecco quale sarà il nostro Dockerfile:

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

Utilizzando l'opzione idea.config.path abbiamo costretto IDEA a cercare la sua configurazione globale nella cartella /etc/idea, perché la cartella home dell’utente quando lavora in CI è una cosa incerta e spesso del tutto assente.

Ecco come appare il file copiato nel contenitore: jdk.table.xml, che contiene i percorsi di OpenJDK installato all'interno del contenitore (è possibile prendere come base un file simile dalla propria directory con le impostazioni 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>

L'immagine finita disponibile su Docker Hub.

Prima di proseguire, controlliamo che l'analizzatore IDEA sia in esecuzione nel contenitore:

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

L'analisi dovrebbe essere eseguita correttamente e nella sottocartella target/idea_inspections dovrebbero essere visualizzati numerosi file .xml con i report dell'analizzatore.

Ora non ci sono più dubbi sul fatto che l'analizzatore IDEA possa essere eseguito in modo autonomo in qualsiasi ambiente CI e passiamo al secondo passaggio.

Passaggio 2. Visualizza e analizza il report

Ottenere il report sotto forma di file .xml è già metà dell'opera: ora è necessario renderlo leggibile. E anche i suoi risultati dovrebbero essere utilizzati nei controlli di qualità, la logica per determinare se il cambiamento accettato passa o fallisce secondo criteri di qualità.

Questo ci aiuterà Plug-in Jenkins Warnings NG, uscito a gennaio 2019. Con il suo avvento, molti plugin individuali per lavorare con i risultati dell'analisi statica in Jenkins (CheckStyle, FindBugs, PMD, ecc.) sono ora contrassegnati come obsoleti.

Il plugin è composto da due parti:

  • numerosi raccoglitori di messaggi dell'analizzatore (elenco completo comprende tutti gli analizzatori conosciuti dalla scienza, da AcuCobol a ZPT Lint),
  • un unico visualizzatore di report per tutti loro.

L'elenco delle cose che Warnings NG può analizzare include avvisi del compilatore Java e avvisi dei log di esecuzione di Maven: sebbene siano costantemente visibili, raramente vengono analizzati in modo specifico. Anche i report IntelliJ IDEA sono inclusi nell'elenco dei formati riconosciuti.

Poiché il plugin è nuovo, inizialmente interagisce bene con Jenkins Pipeline. La fase di creazione con la sua partecipazione sarà simile a questa (diciamo semplicemente al plugin quale formato di report riconosciamo e quali file devono essere scansionati):

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

L'interfaccia del report è simile alla seguente:

Esecuzione di ispezioni IntelliJ IDEA su Jenkins

Convenientemente, questa interfaccia è universale per tutti gli analizzatori riconosciuti. Contiene un diagramma interattivo della distribuzione dei reperti per categoria e un grafico della dinamica delle variazioni nel numero di reperti. Puoi effettuare una ricerca veloce nella griglia in fondo alla pagina. L'unica cosa che non funzionava correttamente per le ispezioni IDEA era la possibilità di sfogliare il codice direttamente in Jenkins (anche se per altri report, ad esempio Checkstyle, questo plugin può farlo magnificamente). Sembra che si tratti di un bug nel parser del report IDEA che deve essere corretto.

Tra le caratteristiche di Warnings NG c'è la capacità di aggregare risultati provenienti da diverse fonti in un unico report e programmare Quality Gates, incluso un "cricchetto" per l'assieme di riferimento. È disponibile parte della documentazione di programmazione di Quality Gates qui - tuttavia, non è completo e devi guardare il codice sorgente. D'altra parte, per un controllo completo su ciò che sta accadendo, il "cricchetto" può essere implementato in modo indipendente (vedi mio prima di tutto su questo tema).

conclusione

Prima di iniziare a preparare questo materiale, ho deciso di fare una ricerca: qualcuno ha già scritto su questo argomento su Habré? Ho solo trovato intervista 2017 с Lanydove dice:

Per quanto ne so, non esiste alcuna integrazione con Jenkins o un plugin Maven […] In linea di principio, qualsiasi appassionato potrebbe fare amicizia con IDEA Community Edition e Jenkins, molti ne trarrebbero solo beneficio.

Bene, due anni dopo abbiamo Warnings NG Plugin e finalmente questa amicizia è arrivata a buon fine!

Fonte: habr.com

Aggiungi un commento