Jenkins での IntelliJ IDEA インスペクションの実行

IntelliJ IDEA は現在、最も高度な静的 Java コード アナライザーを備えており、その機能においては、次のような「ベテラン」を大きく引き離しています。 チェックスタイル и スポットバグ。 その多数の「検査」により、コーディング スタイルから典型的なバグに至るまで、さまざまな側面からコードがチェックされます。

ただし、分析結果が開発者の IDE のローカル インターフェイスに表示されるだけである限り、開発プロセスにはほとんど役に立ちません。 静的解析 満たさなければなりません ビルド パイプラインの最初のステップとして、その結果によって品質ゲートが定義される必要があり、品質ゲートを通過しない場合、ビルドは失敗する必要があります。 TeamCity CI は IDEA と統合されていることが知られています。 ただし、TeamCity を使用しない場合でも、他の CI サーバーで IDEA インスペクションの実行を簡単に試すことができます。 IDEA Community Edition、Jenkins、および Warnings NG プラグインを使用してこれを行う方法を確認することをお勧めします。

ステップ 1. コンテナーで分析を実行し、レポートを取得します。

最初は、グラフィカル インターフェイスを持たない CI システム内で IDE (デスクトップ アプリケーション!) を実行するという考えは、疑わしく、非常に面倒に思えるかもしれません。 幸いなことに、IDEA 開発者は、 コードのフォーマット и 検査 コマンドラインから。 さらに、このモードで IDEA を実行する場合、グラフィック サブシステムは必要なく、これらのタスクはテキスト シェルを備えたサーバー上で実行できます。

検査はスクリプトを使用して開始されます bin/inspect.sh IDEA インストール ディレクトリから。 必要なパラメータは次のとおりです。

  • プロジェクトへのフルパス (相対パスはサポートされていません)、
  • 検査設定を含む .xml ファイルへのパス (通常はプロジェクト内の .idea/inspectionProfiles/Project_Default.xml にあります)、
  • 分析結果に関するレポートを含む .xml ファイルが保存されるフォルダーへのフルパス。

さらに、次のことが期待されます。

  • Java SDK へのパスは IDE で構成されます。それ以外の場合、分析は機能しません。 これらの設定は構成ファイルに含まれています jdk.table.xml IDEA グローバル構成フォルダー内。 IDEA グローバル設定自体は、デフォルトではユーザーのホーム ディレクトリにありますが、この場所は 明示的に指定できる ファイル内 idea.properties.
  • 分析されるプロジェクトは有効な IDEA プロジェクトである必要があり、通常はバージョン管理に無視されるいくつかのファイルをコミットする必要があります。
    • .idea/inspectionProfiles/Project_Default.xml — アナライザー設定。コンテナーで検査を実行するときに明らかに使用されます。
    • .idea/modules.xml - そうしないと、「このプロジェクトにはモジュールが含まれていません」というエラーが表示されます。
    • .idea/misc.xml - そうしないと、「JDK がこのプロジェクトに対して適切に構成されていません」というエラーが表示されます。
    • *.iml-файлы — そうしないと、モジュール内の未構成の JDK に関するエラーが発生します。

これらのファイルは通常、 .gitignore、ファイルなどとは異なり、特定の開発者の環境に固有の情報は含まれません。 workspace.xml、そのような情報が含まれているため、コミットする必要はありません。

明らかな解決策は、JDK を IDEA Community Edition とともに、分析されたプロジェクトに「ピットイン」できる形式のコンテナにパッケージ化することです。 適切なベース コンテナーを選択しましょう。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

オプションの使用 idea.config.path IDEA にフォルダー内のグローバル構成を検索させるようにしました。 /etc/ideaCI で作業しているときのユーザーのホーム フォルダーは不確実であり、まったく存在しないことが多いためです。

コンテナにコピーされたファイルは次のようになります。 jdk.table.xmlこれには、コンテナ内にインストールされた OpenJDK へのパスが含まれています (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>

完成イメージ Docker Hub で利用可能.

次に進む前に、IDEA アナライザーがコンテナー内で実行されていることを確認してください。

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

分析は正常に実行され、アナライザー レポートを含む多数の .xml ファイルが target/idea_inspections サブフォルダーに表示されるはずです。

これで、IDEA アナライザーがどの CI 環境でもスタンドアロンで実行できることに疑いの余地がなくなり、XNUMX 番目のステップに進みます。

ステップ 2. レポートの表示と分析

レポートを .xml ファイルの形式で取得するだけで半分は終わりました。次に、レポートを人間が読める形式にする必要があります。 また、その結果は、品質ゲート (受け入れられた変更が品質基準に従って合格か不合格かを決定するロジック) で使用される必要があります。

これは私たちにとって役立ちます Jenkins 警告 NG プラグイン、2019年XNUMX月に発売されました。 この登場により、Jenkins で静的分析結果を操作するための多くの個別のプラグイン (CheckStyle、FindBugs、PMD など) が廃止されたものとしてマークされています。

プラグインは XNUMX つの部分で構成されます。

  • 多数のアナライザー メッセージ コレクター (全リスト AcuCobol から ZPT Lint まで科学的に知られているすべてのアナライザーが含まれます)、
  • 単一のレポート ビューアですべてのレポートを管理できます。

Warnings NG が分析できるもののリストには、Java コンパイラーからの警告と Maven 実行ログからの警告が含まれます。これらは常に表示されますが、具体的に分析されることはほとんどありません。 IntelliJ IDEA レポートも、認識される形式のリストに含まれています。

このプラグインは新しいため、最初は Jenkins Pipeline と適切に対話します。 これが関与するビルド ステップは次のようになります (認識するレポート形式とスキャンする必要があるファイルをプラグインに指示するだけです)。

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

レポートのインターフェイスは次のようになります。

Jenkins での IntelliJ IDEA インスペクションの実行

便利なことに、このインターフェイスはすべての認識されているアナライザーに共通です。 これには、カテゴリ別の発見物の分布を示すインタラクティブな図と、発見数の変化のダイナミクスを示すグラフが含まれています。 ページ下部のグリッドでクイック検索を実行できます。 IDEA インスペクションで正しく動作しなかった唯一の点は、Jenkins でコードを直接参照する機能でした (ただし、他のレポート、たとえば Checkstyle では、このプラグインはこれを美しく実行できます)。 これは IDEA レポート パーサーのバグであり、修正する必要があるようです。

Warnings NG の機能には、さまざまなソースからの調査結果を XNUMX つのレポートに集約し、参照アセンブリの「ラチェット」を含む品質ゲートをプログラムする機能があります。 一部の Quality Gates プログラミング ドキュメントが利用可能です ここで - ただし、これは完全ではないため、ソース コードを確認する必要があります。 一方、何が起こっているかを完全に制御するには、「ラチェット」を独立して実装できます(私の記事を参照) предыдущийпост このテーマについて)。

まとめ

この資料の準備を始める前に、私は検索することにしました。ハブレでこのトピックについて既に書いた人はいるでしょうか? ただ見つけたのは インタビュー2017 с ラニーそこで彼はこう言います。

私の知る限り、Jenkins や Maven プラグインとの統合はありません […] 原理的には、どんな愛好家でも IDEA Community Edition と Jenkins を使うことができ、多くの人はこれによってのみ恩恵を受けるでしょう。

さて、XNUMX 年後、Warnings NG Plugin が完成し、ついにこの友情が実を結びました。

出所: habr.com

コメントを追加します