우아한테크코스 4기/프로젝트
소나큐브 적용기
giron
2022. 8. 15. 23:38
728x90
SonarQube 란
- 정적 코드 분석을 자동을 수행하는 오픈 소스 플랫폼
- 중복 코드, 코딩 표준, 유닛 테스트, 코드 커버리지, 코드 복잡도, 주석, 버그 및 보안 취약점에 대해서 검사하고 결과를 보고서로 작성한다.
- 20개 이상의 언어에 대한 분석이 가능하다.
정적 코드 분석 이란
- 프로그램을 실행하지 않고 소스 코드나 컴파일된 코드를 분석하는 작업
- 프로그램을 실행하지 않고 버그나 취약점을 분석할 수 있다.
- 주로 개발 단계에서 코드의 구조적인 문제나 실수를 찾아내기 위해서 사용한다.
- 코드 작성단계에서 차후 코드를 실행했을 때 발생할 가능성이 높은 문제를 미리 찾고 대처할 수 있다.
- 단순이 버그나 오류를 찾아내는 것 뿐만 아니라 더 좋은 코드를 위한 개선점을 제시한다.
반대로 동적 분석에는 모니터링이나 테스트가 있다.
정적 코드 분석을 위해 SonarQube 를 사용한 이유
- SonarCloud도 있었지만 SonarColud같은 경우는 소나큐브에 비해 한정적 기능을 제공한다.
- 레퍼런스가 많다.
- sonar cloud가 나오기 훨씬 전부터 나왔으므로 안정적이다.
- 오픈 소스 플랫폼이기 때문에 기본적으로 무료로 제공되고 레퍼런스가 많다.
- 20개 이상의 다양한 언어에 대한 검사가 가능하기 때문에 다른 언어로 작성할 때도 SonarQube 를 정적 분석 도구로 사용할 수 있다.
- GitHub, Jenkins 등의 툴과 다양한 방식으로 연동이 가능하다.
SonarQube 동작 개념
- SonarQube Scanner 가 소스코드를 Scan 한다.
- Gradle, Jenkins 등 다양한 플랫폼에서 SonarQube Scanner 를 지원한다.
- SonarQube 어플리케이션이 설치된 서버로 Scan 한 소스코드를 전달한다.
- SonarQube 어플리케이션이 전달받은 소스코드를 분석하여 보고서를 작성한다.
SonarQube 사용 방법
사용 환경
- GitHub & GitHub Actions
- Gradle
- Aws ec2
- ubuntu 22.04
- Arm 아키텍쳐
- java 11
- SonarQube 8.9.9 (lts버전)
사용 개요
- 개발자가 GitHub Repository 에 PR 을 열거나 이미 열려있는 PR 의 branch 에 새로운 commit 을 push 한다.
- GitHub Actions 를 통해 자동으로 Gradle 의 Scanner Task 가 실행된다.
- Scan 된 소스코드가 SonarQube 어플리케이션이 설치된 ec2 서버로 전달된다.
- SonarQube 어플리케이션이 전달받은 소스코드를 분석하여 보고서를 작성한다.
- 보고서 작성이 끝나면 GitHub PR 에 보고서 링크를 남긴다.
적용
ec2 인스턴스에 SonarQube 설치 & 실행
// apt 업데이트 & unzip 설치
$ sudo apt update
$ sudo apt install unzip
소나큐브는 자바로 만들어져있어서 자바8 이상을 설치해야 한다.
// 자바 11 설치
$ wget -O- https://apt.corretto.aws/corretto.key | sudo apt-key add -
sudo add-apt-repository 'deb https://apt.corretto.aws stable main'
$ sudo apt-get update; sudo apt-get install -y java-11-amazon-corretto-jdk
// SonarQube 를 설치할 폴더 생성, 이동
$ sudo mkdir app
$ cd app
$ sudo mkdir sonarqube
$ cd sonarqube
// wget 으로 소나큐브 설치, 압축 해제(설치)
$ sudo wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.9.9.56886.zip
$ sudo unzip sonarqube-8.9.9.56886.zip
- SonarQube 를 sudo 로 설치했기 때문에 SonarQube 의 실행을 위해서는 root 권한이 있어야한다.
- 나의 root user 이름은 ubuntu 였다.
// SonarQube 실행 권한 변경
$ sudo chown -R ubuntu /app/sonarqube
8081로 포트 번호 수정 (우테코에서는 8080과 8081만 인바운드를 열어줘서 8081로 바꿨다)기본 port 번호는 9000이다.
// sonar.properties 파일 에서 소나큐브 포트 수정
vi /app/sonarqube/sonarqube-8.9.9.56886/conf/sonar.properties
...
sonar.web.port=8081
...
// lib 폴더에서 직접 소나큐브의 jar 파일 실행
cd /app/sonarqube/sonarqube-8.9.9.56886/lib
nohup java -jar sonar-application-8.9.9.56886.jar &
원래는 /app/sonarqube/sonarqube-8.9.9.56886/bin 디렉토리에서 sonar.sh파일을 실행시키면 실행이 된다고 한다.
하지만 저희 인스턴스가 arm아키텍처를 사용하므로 jar파일을 직접 실행시켜야 한다.
소나큐브가 아직 arm아키텍처를 지원하지 않는다고 한다.
이제 소나큐브에 ip:8081을 통해서 접근이 가능하다. 기본 계정의 아이디와 비밀번호는 admin 이다.
- SonarQube 어플리케이션에 접근하여 우측 상단의 A를 클릭 -> My Account에 들어간다.
- Security 탭에서 토큰을 생성한다. 생성된 토큰을 저장해둔다.
- 생성된 Token 문자열을 잘 저장해두고 차후 Scanner 를 발동시킬 때 사용한다.
- 그후, projects에 들어가서 프로젝트도 만들어주면 된다.
build.gradle 파일에 Scanner 설정 추가
plugins {
id 'org.sonarqube' version '3.3'
id 'java'
id 'jacoco'
}
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
}
test {
useJUnitPlatform()
finalizedBy 'jacocoTestReport'
}
jacoco {
toolVersion = "0.8.7"
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
html.enabled false
}
}
sonarqube {
properties {
property "sonar.host.url", "SonarQube 서버 url"
property "sonar.login", "SonarQube 어플리케이션에서 생성한 token"
property "sonar.projectKey", "프로젝트 이름"
property "sonar.projectName" , "SonarQube 로 전달할 소스 코드의 이름 or 버전"
property "sonar.sources", "src" // 소스 경로
property "sonar.language", "java" // 언어
property "sonar.sourceEncoding", "UTF-8"
property "sonar.profile", "Sonar way" // SonarQube 에서 분석할 때 적용할 프로필(분석할 수준 설정)
property "sonar.java.binaries", "${buildDir}/classes" // 자바 클래스 파일위치
property "sonar.test.inclusions", "**/*Test.java" // 코드 분석에 사용할 테스트 소스
property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/test/jacocoTestReport.xml" // jacoco 플러그인의 결과 파일
}
}
sonarqube 서버 url이나 login같은 경우는 노출되면 안되므로 해당 property를 지우고 환경변수로 넣어서 사용하면 좋다.
명령어같은 경우는 소나큐브에 들어가면 친절히 알려준다.
./gradlew -Dsonar.login={token} -Dsonar.host.url={sonarqube url}
Scanner 발동을 위한 GitHub Actions 설정
- 개발자가 GitHub Repository 에 PR 을 열거나 이미 열려있는 PR 의 branch 에 새로운 commit 을 push 할 때 Gradle 의 Scanner 를 발동시켜 정적 분석을 자동으로 수행하기 위해서는 GitHub Actions 의 Workflow 를 사용해야 한다.
- GitHub Actions 의 Workflow yml 파일 설정
.github/workflow/sonarqube.yml 파일
name: gongseek-backend-sonarqube
# 하기 내용에 해당하는 이벤트 발생 시 github action 동작
on:
pull_request: # 모든 브랜치에서 PR이 일어났을 때 github action 동작
branches:
- '*'
types: [opened, synchronize]
defaults:
run:
working-directory: ./backend
jobs:
build:
runs-on: ubuntu-22.04 # 실행 환경 지정
steps:
- name: Checkout source code
uses: actions/checkout@v2
analysis:
runs-on: ubuntu-22.04
env:
SONARQUBE_PROJECT_KEY: gongseek
SONARQUBE_URL: ${{secrets.SONARQUBE_URL}}
SONARQUBE_TOKEN: ${{secrets.SONARQUBE_TOKEN}}
PR_NUMBER: ${{github.event.pull_request.number}}
steps:
# 소스코드 체크아웃 수행
- name: Checkout source code
uses: actions/checkout@v2
# gradlw 파일 권한 변경
- name: gradlew permission change
run: sudo chmod 755 gradlew
# Gralde 의 Scanner 발동, 위의 env 에서 선언한 환경변수와 함께 발동
- name: Sonaqube Analysis
run: ./gradlew test sonarqube
-Dsonar.host.url=${{ env.SONARQUBE_URL }}
-Dsonar.projectKey=${{ env.SONARQUBE_PROJECT_KEY }}
-Dsonar.projectName=${{ env.SONARQUBE_PROJECT_KEY }}-${{ env.PR_NUMBER }}
-Dsonar.login=${{ env.SONARQUBE_TOKEN }}
# PR 에 Comment 를 달아주는 스크립트 실행
- name: Comment Sonarqube URL
uses: actions/github-script@v4
with:
script: |
const { SONARQUBE_PROJECT_KEY, SONARQUBE_URL, PR_NUMBER } = process.env
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `📊 ${ SONARQUBE_PROJECT_KEY }-${ PR_NUMBER } 분석 결과 확인하기 [링크](${SONARQUBE_URL})`
})
이제 거의 다 했다. 환경변수를 넣어주기만 하면 된다.
Github Actions에 환경변수 설정
new repository secret을 클릭해서 토큰을 입력해주면 된다.
소나큐브 실행
nohup java -jar sonar-application-8.9.9.56886.jar &
Reference
https://astonishing-message-fd2.notion.site/SonarQube-87663a36f4604441a56dca3357251f9b
728x90