تشغيل عمليات فحص IntelliJ IDEA على Jenkins

تمتلك IntelliJ IDEA اليوم محلل أكواد Java الثابت الأكثر تقدمًا، والذي يتخلف كثيرًا في قدراته عن هؤلاء "المحاربين القدامى" مثل شيكستايل и البقع. تقوم "عمليات التفتيش" العديدة الخاصة بها بفحص الكود في جوانب مختلفة، بدءًا من أسلوب الترميز وحتى الأخطاء النموذجية.

ومع ذلك، طالما أن نتائج التحليل يتم عرضها فقط في الواجهة المحلية لـ IDE الخاص بالمطور، فهي قليلة الفائدة لعملية التطوير. التحليل الساكن يجب الوفاء بها كخطوة أولى في مسار البناء، يجب أن تحدد نتائجه بوابات الجودة، ويجب أن يفشل البناء إذا لم يتم اجتياز بوابات الجودة. من المعروف أن TeamCity CI متكامل مع IDEA. ولكن حتى إذا كنت لا تستخدم TeamCity، يمكنك بسهولة تجربة إجراء عمليات فحص IDEA في أي خادم CI آخر. أقترح عليك أن ترى كيف يمكن القيام بذلك باستخدام البرنامج الإضافي IDEA Community Edition وJenkins وWarnings NG.

الخطوة 1. قم بتشغيل التحليل في الحاوية واحصل على تقرير

في البداية، قد تبدو فكرة تشغيل IDE (تطبيق سطح المكتب!) داخل نظام CI لا يحتوي على واجهة رسومية مشكوك فيها ومزعجة للغاية. لحسن الحظ، قدم مطورو 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 الخاص بنا:

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/idea، لأن المجلد الرئيسي للمستخدم عند العمل في CI يكون أمرًا غير مؤكد وغالبًا ما يكون غائبًا تمامًا.

هذا هو الشكل الذي يبدو عليه الملف المنسوخ إلى الحاوية: 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، وننتقل إلى الخطوة الثانية.

الخطوة 2. عرض التقرير وتحليله

إن الحصول على التقرير في شكل ملفات ‎.xml هو نصف المعركة؛ والآن تحتاج إلى جعله قابلاً للقراءة من قبل الإنسان. ويجب أيضًا استخدام نتائجها في بوابات الجودة - منطق تحديد ما إذا كان التغيير المقبول سينجح أو يفشل وفقًا لمعايير الجودة.

وهذا سوف يساعدنا تحذيرات جينكينز NG البرنامج المساعد، والذي صدر في يناير 2019. مع ظهورها، تم الآن تصنيف العديد من المكونات الإضافية الفردية للعمل مع نتائج التحليل الثابت في Jenkins (CheckStyle، وFindBugs، وPMD، وما إلى ذلك) على أنها قديمة.

يتكون البرنامج المساعد من جزأين:

  • العديد من جامعي رسائل المحلل (القائمة الكاملة يشمل جميع المحللات المعروفة علميا من AcuCobol إلى ZPT Lint)،
  • عارض تقرير واحد لجميعهم.

تتضمن قائمة الأشياء التي يمكن لـ تحذيرات 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')]
    )
}

تبدو واجهة التقرير كما يلي:

تشغيل عمليات فحص IntelliJ IDEA على Jenkins

ومن الملائم أن هذه الواجهة عالمية لجميع المحللين المعترف بهم. يحتوي على رسم تخطيطي تفاعلي لتوزيع الاكتشافات حسب الفئة ورسم بياني لديناميات التغييرات في عدد الاكتشافات. يمكنك إجراء بحث سريع في الشبكة الموجودة أسفل الصفحة. الشيء الوحيد الذي لم يعمل بشكل صحيح في عمليات فحص IDEA هو القدرة على تصفح التعليمات البرمجية مباشرة في Jenkins (على الرغم من أنه بالنسبة للتقارير الأخرى، على سبيل المثال Checkstyle، يمكن لهذا البرنامج الإضافي القيام بذلك بشكل جميل). يبدو أن هذا خطأ في محلل تقرير IDEA ويجب إصلاحه.

من بين ميزات تحذيرات NG هي القدرة على تجميع النتائج من مصادر مختلفة في تقرير واحد وبرنامج بوابات الجودة، بما في ذلك "السقاطة" للتجميع المرجعي. تتوفر بعض وثائق برمجة Quality Gates هنا - ومع ذلك، فهو ليس كاملاً، ويجب عليك إلقاء نظرة على الكود المصدري. من ناحية أخرى، للسيطرة الكاملة على ما يحدث، يمكن تنفيذ "السقاطة" بشكل مستقل (انظر بلدي المنشور السابق حول هذا الموضوع).

اختتام

قبل البدء في إعداد هذه المادة، قررت أن أبحث: هل سبق لأحد أن كتب عن هذا الموضوع عن حبري؟ لقد وجدت فقط مقابلة 2017 с lanyحيث يقول:

بقدر ما أعرف، لا يوجد تكامل مع Jenkins أو مكون إضافي مخضرم [...] من حيث المبدأ، يمكن لأي متحمس تكوين صداقات مع IDEA Community Edition وJenkins، ولن يستفيد الكثيرون إلا من هذا.

حسنًا، بعد مرور عامين، أصبح لدينا برنامج التحذيرات NG الإضافي، وأخيرًا أتت هذه الصداقة بثمارها!

المصدر: www.habr.com

إضافة تعليق