Kör IntelliJ IDEA-inspektioner på Jenkins

IntelliJ IDEA har idag den mest avancerade statiska Java-kodanalysatorn, som i sin kapacitet lämnar långt bakom sådana "veteraner" som Checkstyle и Spotbugs. Dess många "inspektioner" kontrollerar koden i olika aspekter, från kodningsstil till typiska buggar.

Men så länge som analysresultaten endast visas i det lokala gränssnittet för utvecklarens IDE, är de till liten nytta för utvecklingsprocessen. Statisk analys måste uppfyllas Som det första steget i byggpipelinen bör dess resultat definiera kvalitetsgrindar, och bygget bör misslyckas om kvalitetsgrindarna inte passeras. Det är känt att TeamCity CI är integrerat med IDEA. Men även om du inte använder TeamCity kan du enkelt prova att köra IDEA-inspektioner i vilken annan CI-server som helst. Jag föreslår att du ser hur detta kan göras med IDEA Community Edition, Jenkins och Warnings NG plugin.

Steg 1. Kör analysen i behållaren och få en rapport

Till en början kan tanken på att köra en IDE (skrivbordsapplikation!) inuti ett CI-system som inte har ett grafiskt gränssnitt verka tvivelaktig och mycket besvärlig. Lyckligtvis har IDEA-utvecklare gett möjligheten att köra kodformatering и inspektioner från kommandoraden. Dessutom, för att köra IDEA i det här läget, krävs inget grafiskt undersystem och dessa uppgifter kan utföras på servrar med ett textskal.

Inspektioner startas med hjälp av ett skript bin/inspect.sh från IDEA-installationskatalogen. De parametrar som krävs är:

  • fullständig väg till projektet (släkting stöds inte),
  • sökväg till .xml-filen med inspektionsinställningar (vanligtvis placerad i projektet i .idea/inspectionProfiles/Project_Default.xml),
  • fullständig sökväg till mappen där .xml-filer med rapporter om analysresultaten kommer att lagras.

Dessutom förväntas det

  • sökvägen till Java SDK kommer att konfigureras i IDE, annars fungerar inte analysen. Dessa inställningar finns i konfigurationsfilen jdk.table.xml i IDEA globala konfigurationsmappen. Själva IDEA globala konfigurationen finns som standard i användarens hemkatalog, men denna plats kan uttryckligen anges i fil idea.properties.
  • Det analyserade projektet måste vara ett giltigt IDEA-projekt, för vilket du måste commitera några filer som vanligtvis ignoreras för versionskontroll, nämligen:
    • .idea/inspectionProfiles/Project_Default.xml — analysatorinställningar, de kommer uppenbarligen att användas vid inspektioner i behållaren,
    • .idea/modules.xml - annars får vi felet 'Detta projekt innehåller inga moduler',
    • .idea/misc.xml - annars får vi felet "JDK är inte korrekt konfigurerad för detta projekt",
    • *.iml-файлы – annars får vi ett felmeddelande om en okonfigurerad JDK i modulen.

Även om dessa filer vanligtvis ingår i .gitignore, innehåller de ingen information som är specifik för miljön för en viss utvecklare - till skillnad från till exempel en fil workspace.xml, där sådan information finns och det därför inte finns något behov av att begå den.

Den uppenbara lösningen är att paketera JDK tillsammans med IDEA Community Edition i en behållare i en form redo att "pittas" på de analyserade projekten. Låt oss välja en lämplig basbehållare, och det här är vad vår Dockerfile kommer att vara:

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

Använder alternativet idea.config.path vi tvingade IDEA att leta efter dess globala konfiguration i mappen /etc/idea, eftersom användarens hemmapp när han arbetar i CI är en osäker sak och ofta helt frånvarande.

Så här ser filen som kopierats till behållaren ut: jdk.table.xml, som innehåller sökvägarna till OpenJDK installerad i behållaren (en liknande fil från din egen katalog med IDEA-inställningar kan tas som grund):

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>

Den färdiga bilden tillgänglig på Docker Hub.

Innan vi går vidare, låt oss kontrollera att IDEA-analysatorn körs i behållaren:

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

Analysen bör köras framgångsrikt, och många .xml-filer med analysrapporter bör visas i undermappen target/idea_inspections.

Nu råder det ingen tvekan om att IDEA-analysatorn kan köras fristående i vilken CI-miljö som helst, och vi går vidare till det andra steget.

Steg 2. Visa och analysera rapporten

Att få rapporten i form av .xml-filer är halva striden, nu måste du göra den läsbar för människor. Och även dess resultat bör användas i kvalitetsgrindar - logiken för att avgöra om den accepterade förändringen godkänns eller misslyckas enligt kvalitetskriterier.

Detta kommer att hjälpa oss Jenkins Warnings NG Plugin, som släpptes i januari 2019. Med sin tillkomst är många individuella plugins för att arbeta med statiska analysresultat i Jenkins (CheckStyle, FindBugs, PMD, etc.) nu markerade som föråldrade.

Insticksprogrammet består av två delar:

  • många analysator meddelande samlare (hela listan inkluderar alla analysatorer kända för vetenskapen från AcuCobol till ZPT Lint),
  • en enda rapportvisare för dem alla.

Listan över saker som Warnings NG kan analysera inkluderar varningar från Java-kompilatorn och varningar från Mavens exekveringsloggar: även om de är ständigt synliga, analyseras de sällan specifikt. IntelliJ IDEA-rapporter ingår också i listan över erkända format.

Eftersom plugin-programmet är nytt interagerar det initialt bra med Jenkins Pipeline. Byggsteget med dess deltagande kommer att se ut så här (vi berättar helt enkelt för plugin vilket rapportformat vi känner igen och vilka filer som ska skannas):

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

Rapportgränssnittet ser ut så här:

Kör IntelliJ IDEA-inspektioner på Jenkins

Bekvämt är detta gränssnitt universellt för alla erkända analysatorer. Den innehåller ett interaktivt diagram över fyndfördelningen per kategori och en graf över dynamiken i förändringar i antalet fynd. Du kan göra en snabb sökning i rutnätet längst ner på sidan. Det enda som inte fungerade korrekt för IDEA-inspektioner var möjligheten att bläddra i kod direkt i Jenkins (även om för andra rapporter, till exempel Checkstyle, kan detta plugin göra detta vackert). Det ser ut som att detta är en bugg i IDEA-rapportparsern som måste åtgärdas.

Bland funktionerna i Warnings NG är möjligheten att aggregera fynd från olika källor i en rapport och programmera Quality Gates, inklusive en "spärr" för referensenheten. Viss Quality Gates-programmeringsdokumentation finns tillgänglig här - den är dock inte komplett, och du måste titta på källkoden. Å andra sidan, för fullständig kontroll över vad som händer, kan "spärren" implementeras oberoende (se min tidigare inlägg om detta tema).

Slutsats

Innan jag började förbereda det här materialet bestämde jag mig för att söka: har någon redan skrivit om detta ämne på Habré? Jag hittade bara intervju 2017 с lanydär han säger:

Så vitt jag vet finns det ingen integration med Jenkins eller ett maven-plugin […] I princip kan vilken entusiast som helst bli vän med IDEA Community Edition och Jenkins, många skulle bara dra nytta av detta.

Tja, två år senare har vi Warnings NG Plugin, och äntligen har denna vänskap kommit till stånd!

Källa: will.com

Lägg en kommentar