Skip to content

SonarQube 적용하기

giantim edited this page Sep 18, 2020 · 1 revision

개발 환경

  • ubuntu 18.04
  • sonarqube 7.9.4(current lts)
  • sonarqube scanner 4.0
  • maven 3.6.0
  • sonarqube gradle plugin 3.0

순서

Maven 설치 - 3.6.0

[AWS] EC2에 Maven 설치하기

소나큐브 버전에 맞는 메이븐을 설치해준다.

wget 명령어를 이용해 메이븐을 설치할 때 입력하는 주소는 해당 tar파일 url과 동일하다.

메이븐을 설치하기 이전에 자바가 설치되어 있어야 한다.

자바를 설치하는 방법은 다음과 같다.

$ sudo apt upate
$ sudo apt install default-jre
$ sudo apt install default-jdk

위 링크를 참고해 환경변수를 설정하면 메이븐 설치는 완료된다.

SonarQube 설치 - 7.9.4

소나큐브는 명령어로 설치하는 링크를 확인하지 못해서 공식 사이트에서 다운받은 후 ftp로 ec2에 전송해서 설치했다.

Download SonarQube

메이븐 버전과 맞는 lts 버전을 설치했다.

이때 공식 사이트에서는 zip 파일을 제공하므로 ec2에 unzip을 설치해야 압축을 풀 수 있다.

소나큐브의 기본 설정 포트는 9000번인데 우리 ec2는 보안 그룹에 의해 해당 포트가 열려있지 않으므로 8000번 포트로 변경해주었다.

소나큐브의 포트 변경 방법은 소나큐브 설치 경로/conf/sonar.properties 파일의 sonar.web.port 값을 수정해주면 된다.

How to change SonarQube port

SonarQube Scanner 설치

SonarScanner

소나큐브와 마찬가지로 wget 명령어로 다운로드를 하지 못해서 직접 파일을 ec2로 전송해 설치했다.

SonarQube 웹 페이지 관리

위 설치를 모두 마치고 http://[ec2 ip 주소]:8000 로 접속하면 소나큐브 페이지로 이동한다.

초기 관리자 계정은 아이디: admin / 비밀번호: admin 이다.

로그인하면 다음과 같이 프로젝트 정적 분석 페이지로 이동한다.

image

여기서 Administration → Security → Users → Tokens 탭에서 토큰을 생성한다. 해당 토큰을 이용해서 gradle을 이용해 소나큐브 프로젝트를 생성할 것이다.

IntelliJ sonarqube gradle plugin

멀티모듈 기준이다.

root 프로젝트 build.gradle에 다음 의존성을 추가해 소나큐브를 추가한다. 아래에 추가한 사항은 하위 모듈에 공통으로 적용될 속성이다.

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
    }
}

subprojects {

    apply plugin: "org.sonarqube"

		sonarqube {
		        properties {
		            property "sonar.host.url", "https://sonar.themiso.kr"
		            property "sonar.login", "2036ce58eaf842e7512923b39f0a6ebb47e4f883"
		            property "sonar.sources", "src"
		            property "sonar.language", "java"
		            property "sonar.projectVersion", "1.0"
		            property "sonar.sourceEncoding", "UTF-8"
		            property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
		            property "sonar.test.inclusions", "**/*Test.java"
		        }
		    }
}
  • sonar.host.url: ec2에 설치한 소나큐브 경로. 우리는 현재 서브도메인으로 접속중이지만 초기 설치시에는 http://[ec2 ip]:[소나큐브 포트번호] 일 것이다.
  • sonar.login: 소나큐브 로그인 후 발급받은 토큰 정보를 입력한다.
  • sonar.sources: 분석할 소스 파일의 공통 경로를 지정한다.
  • sonar.language: 작성한 코드의 언어를 선택한다. java의 경우 커뮤니티 버전에서 무료로 정적 분석을 할 수 있다.
  • sonar.projectVersion: 소나큐브에서 분석한 소스의 버전을 지정한다.
  • sonar.coverage.jacoco.xmlReportPaths: jacoco 분석 파일을 xml로 만들어준다. 그 경로를 지정해주어야 소나큐브 페이지에서 코드 커버리지를 볼 수 있다.
  • sonar.test.inclusions: 분석에 사용할 테스트 코드의 위치를 지정한다. **/*Test.java의 경우 src 하위의 모든 디렉토리에서 Test.java로 끝나는 파일을 의미한다.

하위 모듈에서 소나큐브 설정은 다음과 같다.

sonarqube {
    properties {
        property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java"
    }
}

instagram-admin 모듈의 설정을 예로 들면 QClass, api 문서화 클래스는 테스트 커버리지에서 제외시킨다.

위와 같이 각 하위 모듈 별 커버리지를 제외해도 되는 클래스를 등록해준다.

소나큐브 task를 실행하려면 jacocoTestReport가 필요하므로 항상 test를 실행한 후에 소나큐브를 실행해야 한다.

문제

./gradlew clean test sonarqube

위와 같이 그래들 명령어를 실행하면 로컬 / ec2 모두 jvm 메모리 부족 오류가 발생한다.

그래들의 경우 빌드, 태스크 속도를 높이기 위해 캐싱을 이용하는데 소나큐브를 한번에 모든 모듈을 실행하면 jvm 메모리 부족 오류가 발생한다.

그래서 이 문제를 해결하기 위해 젠킨스에서 다음과 같은 job 실행 전략을 세웠다.

  1. 배포를 하는 서비스를 빌드한다.

  2. 서비스 빌드가 끝나면 해당 job에서 전체 프로젝트의 테스트를 수행한다.

  3. 테스트가 종료되면 소나큐브 job을 실행시킨다.

  4. 소나큐브 job에서는 새로 레포지토리를 클론하지 않고 배포 서비스 레포지토리로 이동한다.

  5. 그래들 메모리 부족 오류가 발생하지 않도록 그래들 명령어를 다음과 같이 실행한다.

    ./gradlew :hashtagmap-admin:sonarqube
    ./gradlew --stop

    다음과 같이 실행하는 이유는 그래들이 태스크 정보를 캐싱하지 않고 다음 태스크를 실행해야 메모리 부족 오류가 발생하지 않기 때문이다.

Clone this wiki locally