เรียกใช้การตรวจสอบ IntelliJ IDEA บน Jenkins

IntelliJ IDEA ในปัจจุบันมีเครื่องมือวิเคราะห์โค้ด Java แบบสแตติกที่ทันสมัยที่สุด ซึ่งในแง่ของความสามารถนั้น ได้ละทิ้ง "ทหารผ่านศึก" เช่น เช็คสไตล์ и สปอตบั๊ก. "การตรวจสอบ" จำนวนมากจะตรวจสอบโค้ดในด้านต่างๆ ตั้งแต่รูปแบบการเขียนโค้ดไปจนถึงข้อบกพร่องที่เป็นลักษณะเฉพาะ

อย่างไรก็ตาม ตราบใดที่ผลลัพธ์ของการวิเคราะห์แสดงเฉพาะใน IDE ภายในเครื่องของผู้พัฒนาเท่านั้น ผลลัพธ์เหล่านี้ก็ไม่มีประโยชน์ต่อกระบวนการพัฒนา การวิเคราะห์แบบคงที่ จะต้องดำเนินการ เป็นขั้นตอนแรกของการสร้างไปป์ไลน์ ผลลัพธ์จะต้องกำหนดเกทคุณภาพ และบิลด์ต้องล้มเหลวหากเกทคุณภาพล้มเหลว TeamCity CI เป็นที่ทราบกันว่ารวมเข้ากับ IDEA แต่แม้ว่าคุณจะไม่ได้ใช้ TeamCity คุณก็ยังสามารถลองใช้การตรวจสอบ IDEA บนเซิร์ฟเวอร์ CI อื่นๆ ได้ ฉันเสนอเพื่อดูว่าสิ่งนี้สามารถทำได้โดยใช้ปลั๊กอิน IDEA Community Edition, Jenkins และคำเตือน 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 ลงในคอนเทนเนอร์ในรูปแบบที่พร้อมจะ "ตั้งค่า" ในโครงการที่วิเคราะห์ มาเลือกคอนเทนเนอร์ฐานที่เหมาะสมกัน และนี่คือไฟล์ Docker ที่เราได้รับ:

ไฟล์นักเทียบท่า

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 ที่ต้องแก้ไข

ฟีเจอร์หนึ่งของ Warnings NG คือความสามารถในการรวบรวมสิ่งที่ค้นพบจากแหล่งต่างๆ ในรายงานเดียวและโปรแกรม Quality Gates รวมถึงวงล้อสำหรับชุดอ้างอิง มีเอกสารประกอบการเขียนโปรแกรม Quality Gates บางส่วน ที่นี่ - อย่างไรก็ตาม ยังไม่สมบูรณ์ และคุณต้องดูแหล่งที่มา ในทางกลับกัน เพื่อให้สามารถควบคุมสิ่งที่เกิดขึ้นได้อย่างสมบูรณ์ สามารถใช้ "วงล้อ" ได้อย่างอิสระ (ดู my เปรดดี้ ปอสตี เกี่ยวกับหัวข้อนี้)

ข้อสรุป

ก่อนที่จะเริ่มเตรียมเนื้อหานี้ ฉันตัดสินใจดูว่า: มีใครเขียนหัวข้อนี้ใน Habré แล้วหรือยัง ฉันพบเท่านั้น สัมภาษณ์ 2017 с เลนที่มันพูดว่า:

เท่าที่ฉันทราบ ไม่มีการผสานรวมกับ Jenkins หรือปลั๊กอิน Maven [...] ตามหลักการแล้ว ผู้ที่ชื่นชอบสามารถสร้าง IDEA Community Edition และ Jenkins เป็นเพื่อนได้ หลายคนจะได้รับประโยชน์จากสิ่งนี้เท่านั้น

หลังจากสองปีเราก็มีปลั๊กอิน Warnings NG และในที่สุดมิตรภาพนี้ก็เป็นจริง!

ที่มา: will.com

เพิ่มความคิดเห็น