Przeprowadzanie inspekcji IntelliJ IDEA na Jenkinsie

IntelliJ IDEA posiada dziś najbardziej zaawansowany statyczny analizator kodu Java, który w swoich możliwościach pozostawia daleko w tyle takich „weteranów” jak Styl w kratkę и Spotbugi. Jego liczne „kontrole” sprawdzają kod pod różnymi aspektami, od stylu kodowania po typowe błędy.

Jednakże, dopóki wyniki analizy są wyświetlane tylko w lokalnym interfejsie IDE programisty, są one mało przydatne w procesie programowania. Analiza statyczna musi zostać spełniony Jako pierwszy etap potoku kompilacji jego wyniki powinny definiować bramki jakości, a kompilacja powinna zakończyć się niepowodzeniem, jeśli bramki jakości nie zostaną przekroczone. Wiadomo, że TeamCity CI jest zintegrowane z IDEA. Ale nawet jeśli nie korzystasz z TeamCity, możesz łatwo spróbować przeprowadzić inspekcje IDEA na dowolnym innym serwerze CI. Sugeruję, abyś zobaczył, jak można to zrobić za pomocą wtyczki IDEA Community Edition, Jenkins i Warnings NG.

Krok 1. Uruchom analizę w kontenerze i uzyskaj raport

Na początku pomysł uruchomienia IDE (aplikacji desktopowej!) wewnątrz systemu CI nie posiadającego interfejsu graficznego może wydawać się wątpliwy i bardzo kłopotliwy. Na szczęście programiści IDEA udostępnili możliwość uruchamiania formatowanie kodu и inspekcje z wiersza poleceń. Co więcej, aby uruchomić IDEA w tym trybie, nie jest wymagany podsystem graficzny, a zadania te można wykonać na serwerach z powłoką tekstową.

Inspekcje uruchamiane są za pomocą skryptu bin/inspect.sh z katalogu instalacyjnego IDEA. Wymagane parametry to:

  • pełna ścieżka do projektu (względne nie są obsługiwane),
  • ścieżka do pliku .xml z ustawieniami inspekcji (znajdującego się zazwyczaj wewnątrz projektu w pliku .idea/inspectionProfiles/Project_Default.xml),
  • pełna ścieżka do folderu, w którym będą przechowywane pliki .xml z raportami z wynikami analiz.

Ponadto oczekuje się, że

  • ścieżka do pakietu Java SDK zostanie skonfigurowana w IDE, w przeciwnym razie analiza nie będzie działać. Ustawienia te znajdują się w pliku konfiguracyjnym jdk.table.xml w folderze konfiguracji globalnej IDEA. Sama konfiguracja globalna IDEA domyślnie znajduje się w katalogu domowym użytkownika, ale w tej lokalizacji można wyraźnie określić w pliku idea.properties.
  • Analizowany projekt musi być poprawnym projektem IDEA, dla którego będziesz musiał zatwierdzić niektóre pliki, które zwykle są ignorowane przez kontrolę wersji, a mianowicie:
    • .idea/inspectionProfiles/Project_Default.xml — ustawienia analizatora, będą one oczywiście wykorzystywane podczas przeprowadzania inspekcji w kontenerze,
    • .idea/modules.xml - w przeciwnym wypadku otrzymamy błąd 'Ten projekt nie zawiera modułów',
    • .idea/misc.xml - w przeciwnym razie otrzymamy błąd 'JDK nie jest poprawnie skonfigurowany dla tego projektu',
    • *.iml-файлы — w przeciwnym razie otrzymamy błąd o nieskonfigurowanym JDK w module.

Chociaż pliki te są zwykle zawarte w .gitignore, nie zawierają żadnych informacji specyficznych dla środowiska konkretnego dewelopera - w przeciwieństwie np. do pliku workspace.xml, jeżeli takie informacje są zawarte, w związku z czym nie ma potrzeby ich przekazywania.

Oczywistym rozwiązaniem jest spakowanie JDK wraz z IDEA Community Edition do kontenera w formie gotowej do „pitowania” na analizowanych projektach. Wybierzmy odpowiedni kontener bazowy i tak będzie wyglądał nasz plik 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

Korzystanie z opcji idea.config.path zmusiliśmy IDEA do szukania swojej globalnej konfiguracji w folderze /etc/idea, ponieważ folder domowy użytkownika podczas pracy w CI jest rzeczą niepewną i często zupełnie nieobecną.

Tak wygląda plik skopiowany do kontenera: jdk.table.xml, który zawiera ścieżki do OpenJDK zainstalowanego w kontenerze (za podstawę można przyjąć podobny plik z własnego katalogu z ustawieniami 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>

Gotowy obraz dostępne w Docker Hub.

Zanim przejdziemy dalej, sprawdźmy, czy w kontenerze działa analizator IDEA:

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

Analiza powinna przebiegać pomyślnie, a w podfolderze target/idea_inspections powinny pojawić się liczne pliki .xml z raportami analizatora.

Teraz nie ma już wątpliwości, że analizator IDEA można uruchomić samodzielnie w dowolnym środowisku CI i przechodzimy do kroku drugiego.

Krok 2. Wyświetl i przeanalizuj raport

Uzyskanie raportu w postaci plików .xml to połowa sukcesu, teraz musisz sprawić, by był czytelny dla człowieka. A także jej wyniki należy wykorzystać w bramkach jakości - logice ustalania, czy zaakceptowana zmiana przejdzie, czy nie, zgodnie z kryteriami jakości.

To nam pomoże Wtyczka Jenkins Warnings NG, który ukazał się w styczniu 2019 r. Wraz z jego pojawieniem się wiele indywidualnych wtyczek do pracy z wynikami analizy statycznej w Jenkins (CheckStyle, FindBugs, PMD itp.) zostało oznaczonych jako przestarzałe.

Wtyczka składa się z dwóch części:

  • liczne moduły zbierające komunikaty analizatora (pełna lista obejmuje wszystkie analizatory znane nauce od AcuCobol po ZPT Lint),
  • jedna przeglądarka raportów dla nich wszystkich.

Lista rzeczy, które Warnings NG może analizować, obejmuje ostrzeżenia z kompilatora Java i ostrzeżenia z dzienników wykonania Mavena: chociaż są one stale widoczne, rzadko są szczegółowo analizowane. Raporty IntelliJ IDEA znajdują się również na liście rozpoznawanych formatów.

Ponieważ wtyczka jest nowa, początkowo dobrze współpracuje z Jenkins Pipeline. Krok kompilacji z jego udziałem będzie wyglądał następująco (po prostu informujemy wtyczkę, jaki format raportu rozpoznajemy i jakie pliki należy skanować):

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

Interfejs raportu wygląda następująco:

Przeprowadzanie inspekcji IntelliJ IDEA na Jenkinsie

Dogodnie, interfejs ten jest uniwersalny dla wszystkich uznanych analizatorów. Zawiera interaktywny diagram rozkładu znalezisk według kategorii oraz wykres dynamiki zmian liczby znalezisk. Możesz przeprowadzić szybkie wyszukiwanie w siatce u dołu strony. Jedyne co nie działało poprawnie w przypadku inspekcji IDEA to możliwość przeglądania kodu bezpośrednio w Jenkinsie (chociaż w przypadku innych raportów, np. Checkstyle, ta wtyczka potrafi to pięknie zrobić). Wygląda na to, że jest to błąd w parserze raportów IDEA, który należy naprawić.

Wśród funkcji Warnings NG znajduje się możliwość agregowania ustaleń z różnych źródeł w jednym raporcie i programowaniu bramek jakości, w tym „zapadki” dla zespołu referencyjnego. Dostępna jest dokumentacja programowa Quality Gates tutaj - jednak nie jest ona kompletna i trzeba zajrzeć do kodu źródłowego. Z drugiej strony, aby uzyskać pełną kontrolę nad tym, co się dzieje, „zapadkę” można wdrożyć niezależnie (patrz mój Poprzedni post o tym temacie).

wniosek

Zanim zacząłem przygotowywać ten materiał, postanowiłem poszukać: czy ktoś już pisał na ten temat na Habré? tylko znalazłem wywiad 2017 с leniwygdzie mówi:

Z tego co wiem nie ma integracji z Jenkinsem ani wtyczką maven […] W zasadzie każdy entuzjasta mógłby zaprzyjaźnić się z IDEA Community Edition i Jenkinsem, wielu by na tym tylko skorzystało.

Cóż, dwa lata później mamy wtyczkę Warnings NG i w końcu ta przyjaźń doszła do skutku!

Źródło: www.habr.com

Dodaj komentarz