Nagpapatakbo ng mga inspeksyon ng IntelliJ IDEA kay Jenkins

Ang IntelliJ IDEA ngayon ay may pinaka-advanced na static Java code analyzer, na sa mga kakayahan nito ay nag-iiwan ng malayo sa mga "beterano" tulad ng Checkstyle ΠΈ Spotbugs. Sinusuri ng maraming "inspeksyon" nito ang code sa iba't ibang aspeto, mula sa istilo ng coding hanggang sa mga karaniwang bug.

Gayunpaman, hangga't ang mga resulta ng pagsusuri ay ipinapakita lamang sa lokal na interface ng IDE ng developer, ang mga ito ay walang gaanong pakinabang sa proseso ng pagbuo. Static na pagsusuri dapat matupad Bilang unang hakbang ng build pipeline, ang mga resulta nito ay dapat tukuyin ang kalidad ng mga gate, at ang build ay dapat mabigo kung ang mga kalidad na gate ay hindi naipasa. Ito ay kilala na ang TeamCity CI ay isinama sa IDEA. Ngunit kahit na hindi ka gumagamit ng TeamCity, maaari mong madaling subukang magpatakbo ng mga pag-inspeksyon ng IDEA sa anumang iba pang server ng CI. Iminumungkahi kong tingnan mo kung paano ito magagawa gamit ang IDEA Community Edition, Jenkins at Warnings NG plugin.

Hakbang 1. Patakbuhin ang pagsusuri sa lalagyan at kumuha ng ulat

Sa una, ang ideya ng pagpapatakbo ng isang IDE (desktop application!) sa loob ng isang CI system na walang graphical na interface ay maaaring mukhang kahina-hinala at napakahirap. Sa kabutihang palad, ang mga developer ng IDEA ay nagbigay ng kakayahang tumakbo pag-format ng code ΠΈ mga inspeksyon mula sa command line. Bukod dito, upang patakbuhin ang IDEA sa mode na ito, hindi kinakailangan ang isang graphics subsystem at ang mga gawaing ito ay maaaring gawin sa mga server na may isang text shell.

Inilunsad ang mga inspeksyon gamit ang isang script bin/inspect.sh mula sa direktoryo ng pag-install ng IDEA. Ang mga parameter na kinakailangan ay:

  • buong landas sa proyekto (ang mga kamag-anak ay hindi suportado),
  • path sa .xml file na may mga setting ng inspeksyon (karaniwang matatagpuan sa loob ng proyekto sa .idea/inspectionProfiles/Project_Default.xml),
  • buong path sa folder kung saan iimbak ang mga .xml file na may mga ulat sa mga resulta ng pagsusuri.

Bilang karagdagan, ito ay inaasahan na

  • ang landas sa Java SDK ay mai-configure sa IDE, kung hindi ay hindi gagana ang pagsusuri. Ang mga setting na ito ay nakapaloob sa configuration file jdk.table.xml sa folder ng pangkalahatang configuration ng IDEA. Ang pangkalahatang configuration ng IDEA mismo ay matatagpuan sa home directory ng user bilang default, ngunit ang lokasyong ito maaaring tahasang tukuyin sa file idea.properties.
  • ang proyektong sinusuri ay dapat na isang wastong proyekto ng IDEA, kung saan kakailanganin mong gumawa ng ilang mga file na karaniwang hindi pinapansin sa kontrol ng bersyon, katulad ng:
    • .idea/inspectionProfiles/Project_Default.xml β€” mga setting ng analyzer, malinaw na gagamitin ang mga ito kapag nagpapatakbo ng mga inspeksyon sa lalagyan,
    • .idea/modules.xml - kung hindi, makakakuha tayo ng error na 'Walang mga module ang proyektong ito',
    • .idea/misc.xml - kung hindi, makakakuha tayo ng error na 'Ang JDK ay hindi na-configure nang maayos para sa proyektong ito',
    • *.iml-Ρ„Π°ΠΉΠ»Ρ‹ β€” kung hindi, makakakuha tayo ng error tungkol sa hindi naka-configure na JDK sa module.

Bagama't ang mga file na ito ay karaniwang kasama sa .gitignore, hindi sila naglalaman ng anumang impormasyong partikular sa kapaligiran ng isang partikular na developer - hindi katulad, halimbawa, isang file workspace.xml, kung saan nakapaloob ang naturang impormasyon, at samakatuwid ay hindi na kailangang gawin ito.

Ang malinaw na solusyon ay i-package ang JDK kasama ang IDEA Community Edition sa isang lalagyan sa isang form na handa nang "i-pitted" sa mga nasuri na proyekto. Pumili tayo ng angkop na base container, at ito ang magiging Dockerfile natin:

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

Gamit ang opsyon idea.config.path pinilit namin ang IDEA na hanapin ang global configuration nito sa folder /etc/idea, dahil ang home folder ng user kapag nagtatrabaho sa CI ay isang hindi tiyak na bagay at kadalasang ganap na wala.

Ito ang hitsura ng file na kinopya sa lalagyan jdk.table.xml, na naglalaman ng mga path patungo sa OpenJDK na naka-install sa loob ng container (isang katulad na file mula sa iyong sariling direktoryo na may mga setting ng IDEA ay maaaring kunin bilang batayan):

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>

Ang natapos na imahe available sa Docker Hub.

Bago magpatuloy, tingnan natin kung ang IDEA analyzer ay tumatakbo sa container:

docker run --rm -v <ΠΏΡƒΡ‚ΡŒ/ΠΊ/Π²Π°ΡˆΠ΅ΠΌΡƒ/ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ>:/var/project inponomarev/intellij-idea-analyzer

Dapat na matagumpay na tumakbo ang pagsusuri, at maraming .xml na file na may mga ulat ng analyzer ang dapat lumabas sa subfolder ng target/idea_inspections.

Ngayon ay wala nang anumang pagdududa na ang IDEA analyzer ay maaaring patakbuhin nang nakapag-iisa sa anumang CI environment, at kami ay lumipat sa pangalawang hakbang.

Hakbang 2. Ipakita at suriin ang ulat

Ang pagkuha ng ulat sa anyo ng mga .xml na file ay kalahati ng labanan; ngayon ay kailangan mo itong gawing nababasa ng tao. At gayundin ang mga resulta nito ay dapat gamitin sa mga gate ng kalidad - ang lohika para sa pagtukoy kung ang tinanggap na pagbabago ay pumasa o nabigo ayon sa pamantayan ng kalidad.

Makakatulong ito sa atin Jenkins Warnings NG Plugin, na inilabas noong Enero 2019. Sa pagdating nito, maraming indibidwal na plugin para sa pagtatrabaho sa mga resulta ng static na pagsusuri sa Jenkins (CheckStyle, FindBugs, PMD, atbp.) ay minarkahan na ngayon bilang hindi na ginagamit.

Ang plugin ay binubuo ng dalawang bahagi:

  • maraming mga kolektor ng mensahe ng analyzer (buong listahan kasama ang lahat ng mga analyzer na kilala sa agham mula sa AcuCobol hanggang ZPT Lint),
  • isang viewer ng ulat para sa kanilang lahat.

Kasama sa listahan ng mga bagay na masusuri ng Warnings NG ang mga babala mula sa Java compiler at mga babala mula sa Maven execution logs: bagama't palagi silang nakikita, bihira silang partikular na sinusuri. Ang mga ulat ng IntelliJ IDEA ay kasama rin sa listahan ng mga kinikilalang format.

Dahil bago ang plugin, una itong nakikipag-ugnayan nang maayos sa Jenkins Pipeline. Magiging ganito ang hakbang sa pagbuo kasama ang paglahok nito (sinasabi lang namin sa plugin kung anong format ng ulat ang kinikilala namin at kung anong mga file ang dapat i-scan):

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

Mukhang ganito ang interface ng ulat:

Nagpapatakbo ng mga inspeksyon ng IntelliJ IDEA kay Jenkins

Sa madaling paraan, ang interface na ito ay pangkalahatan para sa lahat ng kinikilalang analyzer. Naglalaman ito ng interactive na diagram ng distribusyon ng mga nahanap ayon sa kategorya at isang graph ng dynamics ng mga pagbabago sa bilang ng mga nahanap. Maaari kang magsagawa ng mabilis na paghahanap sa grid sa ibaba ng pahina. Ang tanging bagay na hindi gumana nang tama para sa mga inspeksyon ng IDEA ay ang kakayahang mag-browse ng code nang direkta sa Jenkins (bagaman para sa iba pang mga ulat, halimbawa Checkstyle, magagawa ito ng plugin na ito nang maganda). Mukhang isa itong bug sa IDEA report parser na kailangang ayusin.

Kabilang sa mga tampok ng Warnings NG ay ang kakayahang pagsama-samahin ang mga natuklasan mula sa iba't ibang mapagkukunan sa isang ulat at programa ng Quality Gates, kabilang ang isang "ratchet" para sa reference assembly. Available ang ilang dokumentasyon ng programming ng Quality Gates dito - gayunpaman, hindi ito kumpleto, at kailangan mong tingnan ang source code. Sa kabilang banda, para sa kumpletong kontrol sa kung ano ang nangyayari, ang "ratchet" ay maaaring ipatupad nang nakapag-iisa (tingnan ang aking Nakaraang post tungkol sa temang ito).

Konklusyon

Bago simulan ang paghahanda ng materyal na ito, nagpasya akong maghanap: may nakasulat na ba sa paksang ito sa Habré? nahanap ko lang panayam 2017 с Lanykung saan sinasabi niya:

Sa pagkakaalam ko, walang integration sa Jenkins o isang maven plugin […] Sa prinsipyo, maaaring makipagkaibigan ang sinumang mahilig sa IDEA Community Edition at Jenkins, marami lang ang makikinabang dito.

Well, makalipas ang dalawang taon mayroon kaming Warnings NG Plugin, at sa wakas ang pagkakaibigang ito ay natupad na!

Pinagmulan: www.habr.com

Magdagdag ng komento