SonarQube는 정적 코드 분석 도구로, 코드 품질을 점검하고 버그, 취약점, 코드 스멜 등을 찾아내어 개발자가 더 나은 코드를 작성할 수 있게 도와준다.
# Docker 설치 (Amazon Linux 2 기준)
sudo yum update -y
sudo yum install docker -y
sudo service docker start
sudo usermod -aG docker ec2-user
# SonarQube 개발용 Docker 컨테이너 시작
sudo docker run -d --name sonarqube \
-p 9000:9000 \
-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
sonarqube:lts
Windows 환경에서는 Docker Desktop을 켜줘야 http://localhost:9000
으로 접근 가능하다.
Docker Desktop 설치 방법
루트 모듈에는 공통 plugin
적용하고 공통으로 사용될 projectKy
, host.url
, login
을 작성해줬다.
plugins {
id 'org.sonarqube' version '4.4.1.3373' // 소나큐브 분석용 플러그인
}
sonarqube {
properties {
property "sonar.projectKey", "coupang-clone" // 소나큐브 프로젝트 키
property "sonar.host.url", "http://localhost:9000" // 실행된 SonarQube 주소
property "sonar.login", System.getenv("SONAR_TOKEN") // 환경변수로 토큰 사용
}
}
sonar.login
을 하드코딩하지 않고 System.getenv("SONAR_TOKEN")
으로 환경변수를 읽도록 구성하면 보안에 안전하고 팀 협업 시에도 노출 위험을 줄일 수 있다.
난 Intelij 터미널이 Windows PowerShell이었어서 아래와 같이 환경변수 설정을 해줬다.
$env:SONAR_TOKEN="token"
💡 환경에 따른 환경변수 설정 방법
환경 | 명령어 예시 |
---|---|
Git Bash | export SONAR_TOKEN="token" |
PowerShell | $env:SONAR_TOKEN="token" |
CMD | set SONAR_TOKEN=token |
서브 모듈에선 각 모듈에 맞는 필요한 설정을 해줬다.
plugins {
id 'java'
id 'jacoco' // 코드 커버리지 측정용
}
apply plugin: 'org.sonarqube'
sonarqube {
properties {
// 소스 코드 경로를 지정 (기본 Java 코드가 위치한 곳)
property "sonar.sources", "src/main/java"
// 테스트 코드 경로를 지정
property "sonar.tests", "src/test/java"
// 컴파일된 클래스 파일 경로 (테스트 커버리지를 계산할 때 필요)
property "sonar.java.binaries", "build/classes/java/main"
// JaCoCo가 생성한 테스트 커버리지 리포트의 XML 경로
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml"
}
}
jacoco {
toolVersion = "0.8.10" // JaCoCo 버전 지정
}
jacocoTestReport {
dependsOn test // 테스트 후 리포트 생성
reports {
xml.required = true // 소나큐브는 XML 리포트를 사용함
html.required = true // 사람이 보기 위한 HTML 리포트 생성
csv.required = false
}
}
sonar.tests
, sonar.coverage.jacoco.xmlReportPaths
는 테스트 코드가 존재하고, jacocoTestReport
를 사용하는 모듈에만 추가해야 정상 동작한다. 테스트가 없는 모듈에선 jacocoTestReport.xml
파일이 생성되지 않기 때문에 해당 설정이 있으면 오류가 난다.
분석 실행 명령어
./gradlew clean test jacocoTestReport sonar
이 명령어는 테스트 -> 커버리지 리포트 생성 -> 소나큐브 분석까지 한 번에 실행한다.
처음에 소나큐브를 설정할 때 루트 gralde에서 모든 것을 하려고 했다. 그러니 제대로 작동하지 않았고 결국 각 모듈마다 설정을 해줬다. 왜냐하면 test가 있는 모듈이 있고 없는 모듈이 있기 때문이었다. 그래서 따로 설정해주니 잘 작동하였다. 멀티 모듈 구조에서는 루트와 서브 모듈 설정을 역할 분리하여 관리하는 것이 훨씬 좋다고 느꼈다.
이후 EC2에도 적용하려 했으나 EC2 프리티어에서는 SonarQube가 매우 무거워 실행 시 렉이 심하고 정상 작동이 어렵다. 실제로 Docker는 정상 실행되지만 Elasticsearch가 메모리 부족으로 crash되거나 응답이 지연되는 현상이 발생했기에, EC2에서는 SonarQube 실행을 포기하고 로컬에서만 분석하도록 결정했다.