Voer IntelliJ IDEA-inspecties uit op Jenkins

IntelliJ IDEA heeft tegenwoordig de meest geavanceerde statische Java-code-analysator, die qua mogelijkheden zulke "veteranen" als Controlestijl и Spotbugs. De talrijke "inspecties" controleren de code op verschillende aspecten, van codeerstijl tot karakteristieke bugs.

Zolang de resultaten van de analyse echter alleen in de lokale IDE van de ontwikkelaar worden weergegeven, hebben ze weinig nut voor het ontwikkelingsproces. Statische analyse moet uitgevoerd worden als eerste stap van de build-pijplijn moeten de resultaten de kwaliteitspoorten bepalen, en de build moet mislukken als de kwaliteitspoorten falen. Het is bekend dat TeamCity CI is geïntegreerd met IDEA. Maar zelfs als u TeamCity niet gebruikt, kunt u nog steeds proberen IDEA-inspecties uit te voeren op elke andere CI-server. Ik stel voor om te zien hoe dit kan worden gedaan met behulp van IDEA Community Edition, Jenkins en Warnings NG-plug-in.

Stap 1. Voer de analyse uit in een container en ontvang een rapport

In eerste instantie lijkt het idee om een ​​IDE (desktop-applicatie!) te draaien binnen een CI-systeem dat geen grafische interface heeft, dubieus en erg lastig. Gelukkig hebben de IDEA-ontwikkelaars de mogelijkheid geboden om te draaien code opmaak и inspecties vanaf de opdrachtregel. Bovendien is er geen grafisch subsysteem nodig om IDEA in deze modus uit te voeren en kunnen deze taken worden uitgevoerd op servers met een tekstshell.

Inspecties worden gestart met behulp van een script bin/inspect.sh vanuit de IDEA-installatiemap. De benodigde parameters zijn:

  • volledig pad naar het project (relatieve worden niet ondersteund),
  • pad naar het .xml-bestand met inspectie-instellingen (meestal te vinden in het project in .idea/inspectionProfiles/Project_Default.xml),
  • volledig pad naar de map waar .xml-bestanden met rapporten met analyseresultaten worden opgeslagen.

Bovendien wordt dat verwacht

  • het pad naar de Java SDK wordt geconfigureerd in de IDE, anders werkt de analyse niet. Deze instellingen zijn opgenomen in het configuratiebestand. jdk.table.xml in de globale configuratiemap van IDEA. De standaard globale IDEA-configuratie zelf bevindt zich in de thuismap van de gebruiker, maar deze locatie kan expliciet worden ingesteld in bestand idea.properties.
  • het geanalyseerde project moet een geldig IDEA-project zijn, waarvoor sommige bestanden die gewoonlijk worden genegeerd, moeten worden vastgelegd voor versiebeheer, namelijk:
    • .idea/inspectionProfiles/Project_Default.xml — analysatorinstellingen, deze worden uiteraard gebruikt bij het starten van inspecties in de container,
    • .idea/modules.xml - anders krijgen we de foutmelding 'Dit project bevat geen modules',
    • .idea/misc.xml - anders krijgen we de foutmelding 'De JDK is niet correct geconfigureerd voor dit project',
    • *.iml-файлы - anders krijgen we een foutmelding over een niet-geconfigureerde JDK in de module.

Hoewel deze bestanden meestal zijn opgenomen in .gitignore, bevatten ze geen informatie die specifiek is voor de omgeving van een bepaalde ontwikkelaar - in tegenstelling tot bijvoorbeeld een bestand workspace.xml, waar dergelijke informatie rechtvaardig is, en daarom is het niet nodig om het te plegen.

Op zichzelf suggereert de uitweg zichzelf om de JDK samen met IDEA Community Edition in een container te verpakken in een vorm die klaar is om te worden "ingesteld" op de geanalyseerde projecten. Laten we een geschikte basiscontainer kiezen, en hier is de Dockerfile die we krijgen:

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

De optie gebruiken idea.config.path we hebben IDEA laten zoeken naar de globale configuratie in de map /etc/idea, aangezien de thuismap van de gebruiker in de werkomstandigheden in CI een onbepaald iets is en vaak volledig afwezig is.

Zo ziet het naar de container gekopieerde bestand eruit jdk.table.xml, die de paden bevat naar de OpenJDK die in de container is geïnstalleerd (het kan gebaseerd zijn op een vergelijkbaar bestand uit uw eigen IDEA-instellingenmap):

jdk.tabel.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>

Afgewerkt beeld beschikbaar op Docker Hub.

Laten we, voordat we verder gaan, de IDEA-parser in de container testen:

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

De analyse zou met succes moeten werken en talrijke .xml-bestanden met analysatorrapporten zouden in de submap target/idea_inspections moeten verschijnen.

Nu bestaat er geen twijfel meer dat de IDEA-analyzer offline kan worden uitgevoerd in elke CI-omgeving en gaan we verder met de tweede stap.

Stap 2. Geef het rapport weer en analyseer het

Een rapport krijgen in de vorm van .xml-bestanden is het halve werk, nu moet het leesbaar worden gemaakt voor mensen. En ook de resultaten ervan moeten worden gebruikt in kwaliteitspoorten - de logica om te bepalen of de geaccepteerde wijziging al dan niet slaagt volgens kwaliteitscriteria.

Dit zal ons helpen Jenkins Waarschuwingen NG Plug-indie in januari 2019 werd uitgebracht. Met de introductie zijn veel afzonderlijke plug-ins voor het werken met statische analyseresultaten in Jenkins (CheckStyle, FindBugs, PMD, etc.) nu gemarkeerd als achterhaald.

De plug-in bestaat uit twee delen:

  • talloze analysatorberichtenverzamelaars (volledige lijst omvat alle analysatoren die de wetenschap kent, van AcuCobol tot ZPT Lint),
  • een enkele rapportviewer voor allemaal.

De lijst met dingen die Warnings NG kan parseren, omvat Java-compilerwaarschuwingen en waarschuwingen van Maven-uitvoeringslogboeken: hoewel ze constant in zicht zijn, worden ze zelden doelbewust geanalyseerd. IntelliJ IDEA-rapporten zijn ook opgenomen in de lijst met erkende formaten.

Omdat de plug-in nieuw is, werkt deze aanvankelijk goed samen met de Jenkins-pijplijn. De bouwstap met zijn deelname ziet er als volgt uit (we vertellen de plug-in gewoon welk rapportformaat we herkennen en welke bestanden moeten worden gescand):

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

De rapportinterface ziet er als volgt uit:

Voer IntelliJ IDEA-inspecties uit op Jenkins

Het is handig dat deze interface universeel is voor alle herkenbare parsers. Het bevat een interactieve grafiek van de verdeling van vondsten per categorie en een grafiek van de dynamiek van veranderingen in het aantal vondsten. In het raster onderaan de pagina kunt u snel zoeken. Het enige dat niet correct werkte voor IDEA-inspecties, was de mogelijkheid om de code rechtstreeks in Jenkins te doorzoeken (hoewel deze plug-in voor andere rapporten, zoals Checkstyle, dit prachtig kan). Het lijkt een bug te zijn in de IDEA-rapportparser die moet worden opgelost.

Een van de kenmerken van Warnings NG is de mogelijkheid om bevindingen uit verschillende bronnen samen te voegen in één rapport en Quality Gates-programma, inclusief een ratel voor een referentie-assemblage. Sommige Quality Gates-programmeerdocumentatie is beschikbaar hier - het is echter niet compleet en u moet naar de bron kijken. Aan de andere kant, voor volledige controle over wat er gebeurt, kan de "ratel" onafhankelijk worden geïmplementeerd (zie mijn едыдущий ост over dit thema).

Conclusie

Voordat ik begon met het voorbereiden van dit materiaal, besloot ik te kijken: heeft iemand al over dit onderwerp geschreven op Habré? Ik heb alleen gevonden gesprek 2017 с lanywaar staat:

Voor zover ik weet is er geen integratie met Jenkins of een maven-plug-in [...] In principe zou elke liefhebber IDEA Community Edition en Jenkins vrienden kunnen maken, velen zouden hier alleen maar baat bij hebben.

Nou, na twee jaar hebben we de Warnings NG Plugin, en eindelijk is deze vriendschap uitgekomen!

Bron: www.habr.com

Voeg een reactie