필자의 경우 Jenkins를 이용한 CI/CD를 진행하며 코드 분석 툴로 Jacoco&Sonarqube를 사용하고 있는 상황이며, 더 나은 코드 품질을 위해 Sonarqube의 Rules 설정을 통한 코드컨벤션을 적용하려 합니다.
<Code Convention을 적용하는 이유>
코드 컨벤션이란 읽기 쉽고, 구조적으로 파악하기 쉬운 코드를 작성하기 위한 코딩스타일 규약이다. 즉, 다른 개발자가 자신이 작성하지 않은 코드를 보더라도 빠르고 쉽게 이해할 수 있도록 가독성을 높여준다. 이로인해 유지보수의 비용을 줄일 수 있다!
먼저 필자가 겪은 상황에 대해 먼저 설명드리도록 하겠습니다.
필자의 경우 코드 컨벤션으로 Naver 코드컨벤션을 적용시켜 보려 하였고 다음 Github 링크를 통해 코드컨벤션 룰이 담긴 xml 파일들을 다운받아 주었습니다. 그 후 소나큐브 Rules에 이 xml 파일을 등록해보려 하였으나 실패를 하였고, 프로젝트 내에서 직접 Stylecheck를 진행한 뒤 해당 리포트 파일을 소나큐브로 넘기는 방식을 선택하였습니다. =)
네이버 코드컨벤션에 대한 규칙내용은 아래 링크를 통해 확인할 수 있습니다. =)
(실패한 방식에 대한 정리)
이 방식은 Sonarqube의 Quality Profiles에서 직접 코드컨벤션 xml 파일을 등록하려 했던 방식입니다. =(
먼저 환경설정-마켓플레이스로 들어와주었습니다.
정상적으로 설치가 완료되었다면 소나큐브 재부팅 후 코딩규칭-Repository에 Checkstyle이 추가된 것을 확인할 수 있었습니다.
그 후 다음과 같이 룰을 생성해주었습니다.
필자는 다음과 같이 설정을 하였고 에러를 마주하게 되었습니다.
<원인파악>
처음에는 admin 권한에 대한 문제인줄 알았으나 해당 소나큐브는 개인 로컬에서 Docker 컨테이너로 띄운 소나큐브이며 해당 계정은 admin 권한이기 때문에 이는 문제가 아니라는 것을 깨달았습니다. 여러 레퍼런스를 찾아보았으나 관련된 레퍼런스가 부족하였고 깃헙 이슈를 통해 문제점을 알게 되었습니다.
이는 소나큐브 자체적인 문제로 판단되어지고 과거의 버전에서는 지원이 되었지만 현재의 버전에서는 문제가 발생하는 것으로 파악되어 집니다.
(현재 필자의 소나큐브 버전은 9.7이며, Checkstyle은 10.3.3 버전이였습니다.)
위의 이슈 내용을 보아 현재는 소나큐브의 Rules를 OneByOne으로 커스텀하여 등록하는 방법밖에 없어 보이는 것으로 판단되어 집니다.
(만약 필자가 위의 Issue내용을 잘못 해석한 것이거나 현재의 버전에서 xml 파일을 등록할 수 있는 방법이 있다면 댓글에 알려주시면 감사하겠습니다!)
(변경한 방식)
위의 방식은 현재로써 힘들 것 같아 다른 방식을 생각하게 되었습니다. 우선 build gradle에 Checkstyle 프러그인을 설치한 후 설정을 통해 Naver 코드 컨벤션 xml 을 등록한 후 빌드시 xml report를 만들어 이것을 소나큐브로 넘기는 방식입니다.
//Checkstyle(코드컨벤션 체크) 플러그인 추가
id 'checkstyle'
//checkstyle과 함께 사용
id 'org.ec4j.editorconfig' version '0.0.3'
먼저 xml.report를 생성하기 위해 checkstyle 플러그인을 추가해주었습니다.
//checkstyle 설정
checkstyle {
ignoreFailures = true //분석결과 예외가 발생하면 빌드실패 발생을 제외
// maxWarnings = 0 // 규칙이 어긋나는 코드가 하나라도 있을 경우 빌드 fail
configFile = file('config/checkstyle/naver-checkstyle-rules.xml') // 설정 파일 경로 지정
configProperties = ["suppressionFile" : "config/checkstyle/naver-checkstyle-suppressions.xml"]
reportsDir = file("build/reports/checkstyle-output")
toolVersion = "10.2" // 처음에 낮은 버전을 사용했더니 깨지는 현상이 있었다. 설정파일의 내용에 맞는 버전을 선택
sourceSets = [sourceSets.main] //지정 안해주면 빌드시 compileQuerydslJava 오류 발생
showViolations = false //Whether or not rule violations are to be displayed on the console.
}
check.dependsOn editorconfigCheck
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
checkstyleMain {
reports {
xml.destination = file("${checkstyle.reportsDir}/checkstyle-report.xml") // 리포트 파일의 위치 및 파일명 지정
}
}
그리고 아래에 다음과 같이 Checkstyle에 대한 설정을 추가해줍니다.
더 상세한 설정 방법은 아래 접은글의 링크를 참고해주세요 =)
여기서 configfile의 경로와 configProperties의 경로는 맨위에서 제공한 링크를 통해 네이버 코드컨벤션 파일을 다운받고 자신의 프로젝트에 지정한 경로입니다.
필자는 다음과 같이 프로젝트의 루트 경로에 config라는 디렉토리와 하위경로에 checkstyle이라는 디렉토리를 만들어주었고 이 안에 xml 설정파일들을 넣어주었습니다.
만약 자신이 Querydsl을 사용하고 있다면 아래의 코드를 꼭 추가해주어야 에러가 나지 않습니다. =)
(위의 gradle Checkstyle 설정에는 필자가 미리 넣어두었습니다.)
sourceSets = [sourceSets.main] //지정 안해주면 빌드시 compileQuerydslJava 오류 발생
필자의 경우 처음 설정을 진행할 때 sourceSets을 지정해주지 않았고 빌드시 compileQuerydslJava에서 오류가 났었습니다.
여러가지 체크를 해보았지만 Java 버전이나 gradle 버전 및 gradle 설정도 Intellij 로 잘 잡혀 있던 상태라 왜 이런 에러가 나타나는지 알 수 없었습니다.
그러다 stackoverflow의 한 글을 보았고 위의 설정을 적용하였을 때 문제점이 사라지는 것을 확인할 수 있었습니다.
다시 본론으로 돌아와 정상적으로 빌드가 되어지면 다음과 같이 지정한 경로에 report가 생성된 것을 확인할 수 있습니다!
필자의 경우 CI tool 로 Jenkins를 사용하고 있었기에 Jenkins 설정에 들어가 Sonarqube properties에 아래와 같이 checkstyle에 대한 추가적인 reportPath를 등록해주었습니다.
(아래는 필자가 Jenkins 설정에 등록한 Sonarqube properties에 대한 설정내용입니다.
빨간색 글씨가 추가된 부분입니다.)
sonar.projectKey=[프로젝트key를 입력하면됩니다 =)]
sonar.projectName=[프로젝트 Name을 입력하면됩니다 =)]
sonar.sources=src/main/java
sonar.junit.reportPaths=build/test-results/test
sonar.tests=src/test/java
sonar.test.inclusion=**/*Test.java
sonar.java.binaries=build/classes, target/test-classes
sonar.java.coveragePlugin=jacoco
sonar.coverage.jacoco.xmlReportPaths=build/jacoco/jacoco.xml
sonar.java.libraries.empty=true
sonar.sourceEncoding=UTF-8 sonar.exclusions=**/dto/**,**/exception/**,**/constant/**,**/SpringInitProjectApplication.java,**/WebRestController.java,**/FileUploadYaml.java sonar.java.checkstyle.reportPaths=build/reports/checkstyle-output/checkstyle-report.xml
이제 Jenkins Pipeline을 통해 테스트 빌드를 해보겠습니다.
필자의 경우 미리 Jenkins pipeline 구축을 통해 Slack 과 연동을 해 둔 상태입니다. ㅎㅎ
이에 대한 내용은 정리해둔 글과 github 코드가 있으니 아래 링크를 통해 확인해 주세요. =)
(틈틈이 업데이트를 하는중이니 에러나 수정사항이 필요하다면 댓글에 남겨주시면 감사하겠습니다!)
우선 SonarQube Quality Gate 단계에서 실패를 한 것을 확인할 수 있네요!
그럼 SonarQube 서버에 들어가 무엇이 문제인지 확인해보도록 하겠습니다.
내용을 확인해보니 Maintainability 즉, 유지 보수성 등급이 현재 Checkstyle을 적용함으로써 C 등급으로 떨어졌기 때문에 실패가 된 것으로 확인되어 지네요. =(
우선 Maintainability 항목을 살펴보면 Code Smells라는 항목이 존재하는데 이부분이 코드 룰과 얼만큼 적합한지에 대한 판단의 척도로 보여집니다!
네이버 컨벤션 룰을 적용하였더니 현재 프로젝트에서 엄청나게 Code Smell이 발생하는 군요…ㅜ
우선 소나큐브 내에 해당 프로젝트는 아래와 같이 QualityGate가 Deafault로 설정되어 있어 모든 체킹하는 부분이 높게 잡혀 있을 겁니다. 우선 Success를 시켜보기 위해 한 번 QualityGate를 커스텀해보도록 하겠습니다. =)
Maintainability 부분을 보시면 현재 Default Quality Gate인 Sonar Way는 A등급으로 잡혀 있네요 ㅎㅎ
그럼 새로 Quality Gate를 만들어서 한번 저 부분을 C등급으로 맞추어 보고 Jenkins build 시 통과가 되는지 확인을 해보도록 하겠습니다!
Create를 눌러주신 뒤 자신이 사용하고 싶은 이름을 입력해주도록 하겠습니다.
그 후 Add condition을 눌러 다음과 같이 하나씩 추가를 해주도록 할께요! =)
그리고 이번 테스트에서 가장 중요한 Maintainability를 C등급으로 맞추어 주도록 하겠습니다.
모두 등록을 하였다면 위와 같이 자신이 만든 프로젝트를 체크를 해주어 해당 프로젝트에는 방금 만든 QualityGate를 적용시켜줍니다. =)
잘 적용이 되었는지 확인을 위해 해당 프로젝트 내에 들어와 Project Setting – QualityGate로 들어온 후 위와 같이 설정이 잘 잡혀 있는지 확인할 수 있습니다. 필자의 경우 좀 전에 Project라는 이름의 QualityGate를 생성해 주었고 해당 QualityGate가 설정된 것을 확인할 수 있습니다. =)
그럼 이제 다시 CheckStyle로 인해 무더기로 발견된 code smell로 QualityGate를 통과하지 못했었는데 통과를 할 수 있는지 체킹을 해보도록 하겠습니다!
우선 jenkins Build를 위해 git push를 진행해보도록 하겠습니다. =)
정상적으로 모두 통과되었네요. =)
그럼이제 소나큐브 서버에 접속하여 확인을 해보도록 하겠습니다. =)
Checkstyle report도 정상적으로 넘어오는 것 같고 QualityGate도 통과를 하였네요. =)
CodeSmell이 322개라니….. NaverConvention에 하나씩 맞춰봐야겠군용 ….ㅎㅎㅎ
그럼 이제 모든 셋팅이 끝났으니 이번엔 저 코드스멜을 없애기 위해 Intellij에서 CheckStyle 플러그인을 설치하고 config/checkstyle에 넣어준 naver-checkstyle-rules.xml을 등록하여 쉽게 확인을 할 수 있게 해보도록 하죠. =)
Intellij-Checkstyle
먼저 Intellij의 설정-플러그인에 들어와 CheckStyle-IDEA를 설치해주도록 합시다. 필자는 이미 설치가 되어있습니다. ㅎㅎ
플러그인 설치가 완료되면 Intellij를 재부팅해야 적용이 됩니다. =)
그리고 설정-도구-Checkstyle에 들어와 위와 같이 셋팅을 해준 후 +버튼을 눌러 추가해주도록 하겠습니다! 필자의 경우 이미 Naver Checkstyle Rules라는 이름으로 등록을 해두었는데 등록하는 과정을 설명드리도록 해보죠. =)
+버튼을 누르면 다음과 같은 창이 나오게 되는데 Description에는 자신이 사용하고자 하는 이름을 입력해줍니다. 그 후 File항목의 browse를 눌러 해당 프로젝트의 config/checkstyle/naver-checkstyle-rules.xml 파일을 선택해주도록 합니다!
모두 다하셨다면 next 버튼을 눌러주세요. =)
다음과 같은 창이 나올텐데 여기에는 config/checkstyle/ 에 넣어준 naver-checkstyle-suppressions.xml 파일 이름을 입력해주도록 하겠습니다.
모두 완료하셨다면 자신이 만든 ConfigurationFile을 체크한 후 적용 버튼과 확인을 눌러주세요.=)
모두 적용을 완료하였으니 하단의 Checkstlye을 눌러준 후 Rules에 자신이 등록한 설정으로 변경해줍시다. 그리고 왼쪽의 폴더모양(Check Project)을 클릭하면 다음과 같이 검사가 되고 코드 컨벤션 룰에 어긋난 부분들을 확인할 수 있습니다! =)
이제 어떠한 부분이 문제인지를 알 수 있도록 하였으니 문제를 해결해보아야겠죠?!
Intellij-Formatter
이번에는 IntelliJ Formatter를 naver-intellij-formmater.xml을 이용하여 적용시켜보도록 하겠습니다.=)
필자가 맨처음 네이버 핵데이 깃헙 링크를 남겨두었는데 여기서 프로젝트 파일을 정상적으로 다운받았다면 naver-intellij-formmater.xml 을 가지고 있을겁니다.
설정-에디터-코드스타일-Java 경로로 들어와줍니다.
그리고 위와같이 설정에서 구성표가져오기(import Schema)를 선택하고 Intellij IDEA 코드스타일 XML을 클릭해주도록 하겠습니다. =)
다음과 같이 naver-intellij-formmater.xml 를 선택해 주신 후 확인을 눌러주도록 하겠습니다!
정상적으로 등록이 되었군요. =)
추가적으로 Test 메소드 이름이 한글인 것을 검사하지 않기 위해 추가해주도록 하겠습니다. =)
이제 한 번에 Code Convention을 잡아주기 위해 정말 유용한 플러그인을 설치해보도록 하겠습니다. Save Actions라는 플러그인을 설치해준 후 설정을 해보도록 하겠습니다. =)
설정의 맨 밑에 있는 기타설정의 Save Actions로 들어와 위와 같이 3개를 체크해주도록 하겠습니다.
이제 저장시에 import 최적화와 포메터 룰에 따라 코드가 재정렬 될 것입니다!
이제 프로젝트의 root 디렉토리에서 우클릭을 한 후 다음과 같이 실행을 해주도록 하겠습니다. =)
추가적으로 네이버 코드 컨벤션의 경우 파일의 마지막은 새줄 문자 LF로 끝나야합니다. 필자의 경우 이부분에서 많은 오류가 잡혔는데 이부분은 아래와 같이 설정을 해주어 해결하였습니다. =)
설정이 잘 되었으면 Intellij 하단에 위와 같이 LF로 표기가 되어 있는 것을 확인할 수 있습니다.
(필자의 경우 기존에 CRLF로 잡혀 있는 것을 확인하였습니다.)
모든 설정이 끝난 후 다시 테스트를 진행하였더니 300개 이상이였던 코드컨벤션 위반 사항이 확연히 준 것을 확인하였습니다. =)
다시 Jenkins 빌드를 통해 소나큐브를 확인하였을 때 Code Smells도 확연하게 줄어들어 A로 표시된 것을 확인할 수 있었습니다. =)
이제 다시 QulityGate 설정에서 Maintainability 를 C -> A로 높여야 겠군요. ㅎㅎㅎ
이렇게 수많은 삽질을 하며 Jenkins Stylecheck Sonarqube 콤비를 적용해볼 수 있었습니다.
하나 깨달은 것은 SonarQube에서 직접 CustomProfile을 통해 하나하나 Code Convention Rule을 지정해주는 것도 좋지만 필자가 진행한 방식을 했을 경우 Gradle의 Stylecheck 설정을 통해 빌드시에 실패를 발생시키게 할 수 있고 or
빌드시에는 실패를 하지 않고 Sonarqube의 QualityGate에서 실패를 발생시킬 수 도 있다는 장점이였습니다. =)
'DailyStudy > CI CD' 카테고리의 다른 글
Jenkins&Springboot CI/CD 정리(2) (1) | 2022.11.11 |
---|---|
Jenkins&Springboot CI/CD 정리(1) (0) | 2022.11.05 |
Jenkins & Slack 연동하기(Slack Notification) 및 파이프라인 작성 (0) | 2022.10.27 |
Gitea Webhook Jenkins(Gitea 와 jenkins 연동하기) (1) | 2022.10.11 |
Jenkins를 이용한 CI/CD Pipeline 구축해보기(3) (0) | 2022.10.05 |