Efectuarea de inspecții IntelliJ IDEA pe Jenkins

IntelliJ IDEA are astăzi cel mai avansat analizor de cod Java static, care, prin capacitățile sale, lasă în urmă astfel de „veterani” precum Stil de verificare и Spotbugs. Numeroasele sale „inspecții” verifică codul în diferite aspecte, de la stilul de codare la erori tipice.

Cu toate acestea, atâta timp cât rezultatele analizei sunt afișate doar în interfața locală a IDE-ului dezvoltatorului, ele sunt de puțin folos procesului de dezvoltare. Analiza statica trebuie îndeplinită Ca prim pas al conductei de construcție, rezultatele sale ar trebui să definească porți de calitate, iar construcția ar trebui să eșueze dacă porțile de calitate nu sunt trecute. Se știe că TeamCity CI este integrat cu IDEA. Dar chiar dacă nu utilizați TeamCity, puteți încerca cu ușurință să rulați inspecții IDEA pe orice alt server CI. Vă sugerez să vedeți cum se poate face acest lucru folosind IDEA Community Edition, Jenkins și pluginul Warnings NG.

Pasul 1. Rulați analiza în container și obțineți un raport

La început, ideea de a rula un IDE (aplicație de desktop!) în interiorul unui sistem CI care nu are o interfață grafică poate părea dubioasă și foarte supărătoare. Din fericire, dezvoltatorii IDEA au oferit posibilitatea de a rula formatarea codului и inspecții din linia de comandă. Mai mult, pentru a rula IDEA în acest mod, nu este necesar un subsistem grafic și aceste sarcini pot fi efectuate pe servere cu un shell de text.

Inspecțiile sunt lansate folosind un script bin/inspect.sh din directorul de instalare IDEA. Parametrii necesari sunt:

  • calea completă către proiect (cele relative nu sunt acceptate),
  • calea către fișierul .xml cu setările de inspecție (se află de obicei în interiorul proiectului în .idea/inspectionProfiles/Project_Default.xml),
  • calea completă către folderul în care vor fi stocate fișierele .xml cu rapoarte privind rezultatele analizei.

În plus, este de așteptat ca

  • calea către Java SDK va fi configurată în IDE, altfel analiza nu va funcționa. Aceste setări sunt conținute în fișierul de configurare jdk.table.xml în folderul de configurare globală IDEA. Configurația globală IDEA în sine este localizată în directorul principal al utilizatorului în mod implicit, dar această locație poate fi specificat în mod explicit în dosar idea.properties.
  • Proiectul analizat trebuie să fie un proiect IDEA valid, pentru care va trebui să comiți câteva fișiere care de obicei sunt ignorate pentru controlul versiunilor și anume:
    • .idea/inspectionProfiles/Project_Default.xml — setările analizorului, acestea vor fi în mod evident utilizate la efectuarea inspecțiilor în container;
    • .idea/modules.xml - altfel vom primi eroarea „Acest proiect nu conține module”,
    • .idea/misc.xml - altfel vom primi eroarea „JDK-ul nu este configurat corect pentru acest proiect”,
    • *.iml-файлы — în caz contrar, vom primi o eroare despre un JDK neconfigurat în modul.

Deși aceste fișiere sunt de obicei incluse în .gitignore, nu conțin nicio informație specifică mediului unui anumit dezvoltator - spre deosebire de, de exemplu, un fișier workspace.xml, în cazul în care aceste informații sunt conținute și, prin urmare, nu este nevoie să le angajați.

Soluția evidentă este de a împacheta JDK-ul împreună cu IDEA Community Edition într-un container într-o formă gata de a fi „încărcat” pe proiectele analizate. Să alegem un container de bază potrivit și acesta este ceea ce va fi 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

Folosind opțiunea idea.config.path am forțat IDEA să caute configurația globală în folder /etc/idea, deoarece folderul de acasă al utilizatorului atunci când lucrează în CI este un lucru incert și adesea complet absent.

Iată cum arată fișierul copiat în container: jdk.table.xml, care conține căile către OpenJDK instalate în interiorul containerului (un fișier similar din propriul director cu setări IDEA poate fi luat ca bază):

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>

Imaginea terminată disponibil pe Docker Hub.

Înainte de a continua, să verificăm dacă analizorul IDEA rulează în container:

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

Analiza ar trebui să ruleze cu succes și numeroase fișiere .xml cu rapoarte ale analizorului ar trebui să apară în subdosarul target/idea_inspections.

Acum nu mai există nicio îndoială că analizorul IDEA poate fi rulat independent în orice mediu CI și trecem la pasul al doilea.

Pasul 2. Afișați și analizați raportul

Obținerea raportului sub formă de fișiere .xml este jumătate din luptă; acum trebuie să îl faceți lizibil de către om. Și, de asemenea, rezultatele sale ar trebui folosite în porțile calității - logica pentru a determina dacă schimbarea acceptată trece sau nu în conformitate cu criteriile de calitate.

Acest lucru ne va ajuta Pluginul Jenkins Warnings NG, care a fost lansat în ianuarie 2019. Odată cu apariția sa, multe plugin-uri individuale pentru lucrul cu rezultatele analizei statice în Jenkins (CheckStyle, FindBugs, PMD etc.) sunt acum marcate ca învechite.

Pluginul este format din două părți:

  • numeroși colectori de mesaje de analiză (lista completă include toți analizoarele cunoscute științei de la AcuCobol la ZPT Lint),
  • un singur vizualizator de rapoarte pentru toate acestea.

Lista lucrurilor pe care Warnings NG le poate analiza include avertismente din compilatorul Java și avertismente din jurnalele de execuție Maven: deși sunt vizibile în mod constant, rareori sunt analizate în mod specific. Rapoartele IntelliJ IDEA sunt de asemenea incluse în lista de formate recunoscute.

Deoarece pluginul este nou, inițial interacționează bine cu Jenkins Pipeline. Pasul de construire cu participarea sa va arăta astfel (pur și simplu spunem pluginului ce format de raport recunoaștem și ce fișiere trebuie scanate):

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

Interfața de raport arată astfel:

Efectuarea de inspecții IntelliJ IDEA pe Jenkins

În mod convenabil, această interfață este universală pentru toți analizatorii recunoscuți. Conține o diagramă interactivă a distribuției descoperirilor pe categorii și un grafic al dinamicii modificărilor numărului de descoperiri. Puteți efectua o căutare rapidă în grila din partea de jos a paginii. Singurul lucru care nu a funcționat corect pentru inspecțiile IDEA a fost capacitatea de a răsfoi codul direct în Jenkins (deși pentru alte rapoarte, de exemplu Checkstyle, acest plugin poate face acest lucru frumos). Se pare că acesta este o eroare în analizatorul de rapoarte IDEA care trebuie remediată.

Printre caracteristicile Warnings NG se numără capacitatea de a agrega constatări din diferite surse într-un singur raport și program Quality Gates, inclusiv un „clichet” pentru ansamblul de referință. Unele documentații de programare Quality Gates sunt disponibile aici - cu toate acestea, nu este complet și trebuie să vă uitați la codul sursă. Pe de altă parte, pentru un control complet asupra a ceea ce se întâmplă, „clichet” poate fi implementat independent (vezi postarea anterioară despre această temă).

Concluzie

Înainte de a începe pregătirea acestui material, m-am hotărât să caut: a scris cineva deja pe această temă pe Habré? doar am gasit interviu 2017 с Lanyunde spune:

Din câte știu eu, nu există integrare cu Jenkins sau cu un plugin maven […] În principiu, orice entuziast s-ar putea împrieteni cu IDEA Community Edition și Jenkins, mulți ar beneficia doar de asta.

Ei bine, doi ani mai târziu avem Warnings NG Plugin și, în sfârșit, această prietenie s-a concretizat!

Sursa: www.habr.com

Adauga un comentariu