SonarQube์ Github Action์ผ๋ก ์ํํ๋ ์ ์ ๋ถ์
์๋ ํ์ธ์ Mambo ์ ๋๋ค.
์ค๋์ SonarQube์ Github Action์ ํตํด ์ ์ ๋ถ์์ ์ํํ๊ธฐ ์ํ ๊ณผ์ ์ ์์๋ณด๋ ค๊ณ ํฉ๋๋ค.
SonarQube
์๋ํ๋ธ๋ ๋ค์ํ ์ธ์ด์ ๋ํ ์ฝ๋ ํ์ง์ ๋ถ์ํ๊ณ ์ทจ์ฝ์ ์ ํ์ ํ ์ ์๋ ์ ์ ๋ถ์ ๋๊ตฌ์ ๋๋ค. ํ์ฌ์์ ์ ์ ๋ถ์์ ์ํํ๊ณ ์ถ๋ค๋ ์๊ตฌ์ฌํญ์ด ์์ด ์ ๊ฐ SonarQube๋ฅผ ๋์ ํ๊ณ ์์์ผ๊ณผ ๊ธ์์ผ๋ง๋ค ํ๋ก์ ํธ ์ฝ๋์ ๋ํ ์ ์ ๋ถ์์ ์ํํ๊ณ ์์ต๋๋ค. ์ ๊ฐ ์ ์ ๋ถ์์ ์ํด์ ์๋ํ๋ธ๋ฅผ ๋์ ํ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- GPLv3 ๋ผ์ด์ผ์ค ๊ธฐ๋ฐ์ ์คํ์์ค ๋ฒ์ ์ง์
- IntelliJ ๋๋ VSCode์ ๊ฐ์ IDE๋ฅผ ์ํ SonarLint ์ง์
- ์๋ํ๋ธ์ ๋ํ ๊ณต์ ๋์ปค ์ด๋ฏธ์ง ์ง์
- ๋ค์ํ ์ธ์ด์ ์ปค๋ฎค๋ํฐ ๊ธฐ๋ฐ์ ๊ท์น ์ง์
ํ์ฌ ๊ฐ๋ฐ์๋ค์ด ์ฃผ๋ก ์ฌ์ฉํ๋ ์ธํ ๋ฆฌ์ ์ด IDEA ๋๋ VSCode์์ ์ฌ์ฉํ ์ ์๋ SonarLint๋ฅผ ์ ๊ณตํ์ฌ ๋ณ๋์ ์๋ฒ ์์ด๋ ๊ฐ๋จํ๊ฒ ์์ฒด์ ์ผ๋ก ์ ์ ๋ถ์์ ์ํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ผ๋ฉฐ ๊ณต์ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ํตํด ๋ณ๋ค๋ฅธ ์ค์ ์์ด๋ ๊ฐ๋จํ๊ฒ ์๋ํ๋ธ ์์คํ ์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์๋ํ๋ธ ์์คํ ๊ตฌ์ฑ
์๋ํ๋ธ๋ ์ง์ ์ค์นํ ์๋ ์์ผ๋ฉฐ ๋์ปค ์ด๋ฏธ์ง์ ํจ๊ป ์ ๊ณตํ๋ ๋์ปค ์ปดํฌ์ฆ ๋ฌธ์๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
sq-with-postgres/docker-compose.yml
version: "3.8"
services:
web:
image: sonarqube:9.1.0-community
restart: always
depends_on:
- db
ports:
- "9000:9000"
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
- sonarqube_temp:/opt/sonarqube/temp
- sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins
ulimits:
nproc: 65535
nofile:
soft: 262144
hard: 262144
db:
image: postgres
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
volumes:
- postgresql:/var/lib/postgresql
- postgresql_data:/var/lib/postgresql/data
networks:
sonarnet:
driver: bridge
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
sonarqube_temp:
sonarqube_bundled-plugins:
postgresql:
postgresql_data:
WSL vm.max_map_count
์๋์ฐ ํ๊ฒฝ์์ WSL๋ก ๋์ปค ์ปจํ ์ด๋๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ vm.max_map_count๋ก ์ธํ์ฌ ์๋ํ๋ธ์์ ์คํํ๋ Elasticsearch๊ฐ ์คํ๋์ง ์์ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์๋์ฐ ํฐ๋ฏธ๋์์ WSL๋ก ๋์ปค ์ปจํ ์ด๋๋ก ์ ์ ํ ๋ค์์ ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ Elasticsearch์์ ์๊ตฌํ๋ ์์น๋ก ๋ณ๊ฒฝํ์๋ฉด ๋ฉ๋๋ค.
# Max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144
์๋ํ๋ธ์ ๊ด๋ฆฌ์ ๊ณ์ ๊ณผ ์ด๊ธฐ ๋น๋ฐ๋ฒํธ๋ admin/admin ์ ๋๋ค.
์๋ํ๋ธ ํ๋ก์ ํธ ์์ฑ
์๋ํ๋ธ์ ์ ์ํ์๋ค๋ฉด ์ ์ ๋ถ์์ ์ํํ ํ๋ก์ ํธ๋ฅผ ์์ฑํด์ผํฉ๋๋ค. ์ ๋ ๊นํ๋ธ ๋ฆฌํ์งํ ๋ฆฌ ์ด๋ฆ์ ๊ทธ๋๋ก ์ฌ์ฉํ๋ ํธ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์๋ํ๋ธ์ ๋ก๊ทธ์ธํ ์ ์๋ ํ ํฐ์ ๋ฐํํฉ๋๋ค.
ํ ํฐ ์ฉ๋๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํ ์ด๋ฆ์ ์ง์ ํ๋๋ฐ ์ ๋ Github Action์์ ์ฌ์ฉํ ์์ ์ด๋ฏ๋ก GITHUB_ACTION์ ์ง์ ํ์์ต๋๋ค.
์ ๋ ๋ก์ปฌ ์ปดํจํฐ์ ์๋ํ๋ธ๋ฅผ ์คํํ์๊ณ ํ์ํ ๋๋ง ํฌํธํฌ์๋ฉ์ ์ํํ ์์ ์ด๋ฏ๋ก ํ ํฐ์ ๊ณต๊ฐํ๊ฒ ์ต๋๋ค. (์ด์ฐจํผ ํ์ต ํ์ ์ง์โฆ)
์๋ํ๋ธ ๊ด๋ จ ์ฝ๋ ์ถ๊ฐ
์๋ํ๋ธ ์์คํ ์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ํ ํฐ์ ๋ฐ๊ธํ์๊ธฐ ๋๋ฌธ์ ์๋ํ๋ธ์ ์ฐ๊ณํ ์ ์๋๋ก ํ๋ก์ ํธ ํด๋์ ์๋ํ๋ธ์ ๊ด๋ จ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค.
build.gradle
๋ง์ฝ, ๊ทธ๋๋ค์ ํตํด ์๋ํ๋ธ์ ์ฐ๋ํ๊ณ ์ถ๋ค๋ฉด build.gradle์ SonarQube ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํด์ผํฉ๋๋ค.
plugins {
id "org.sonarqube" version '3.3'
id 'jacoco'
}
sonarqube {
properties {
property "sonar.projectKey", "spring5-web-example"
}
}
sonar-project.properties
sonar-project.properties ํ์ผ์ ์๋ํ๋ธ์์ ์ฐธ์กฐํ๊ฒ ๋๋ ์ค์ ํ์ผ์ ๋๋ค.
sonar.projectKey=spring5-web-example
sonar.projectName=spring5-web-example
sonar.java.source=1.11
sonar.sources=src/main/java
#sonar.tests=src/main/test
sonar.java.binaries=build/classes/java/main/com/example
sonar.sourceEncoding=UTF-8
sonar.exclusions=
Github Action
SonarQube GitHub Action์ Github Action์ ํตํด ์๋ํ๋ธ๋ก ์ ์ ๋ถ์์ ์ํํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
์๋ํ๋ธ ์ํฌํ๋ก์ฐ ์ฝ๋ ์ถ๊ฐ
.github/workflows/sonarqube.yml
on:
# schedule:
# - cron: '0 * * * 1'
workflow_dispatch:
name: SonarQube Workflow
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.11
uses: AdoptOpenJDK/install-jdk@v1
with:
version: '11'
architecture: x64
targets: 'JAVA_HOME'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build -x test
- name: Upload build artifact
uses: actions/upload-artifact@v2
with:
name: build
path: build/classes
sonarQube:
needs: build
name: SonarQube
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Donwload build artifact
uses: actions/download-artifact@v2
with:
name: build
path: build/classes
- name: SonarQube Scan
uses: kitabisa/sonarqube-action@master
with:
host: ${{ secrets.SONAR_HOST }}
login: ${{ secrets.SONAR_TOKEN }}
projectBaseDir: '/github/workspace'
์๋ํ๋ธ ์ํฌํ๋ก์ฐ ํ์ผ์ ๊นํ๋ธ ๋ฆฌํ์งํ ๋ฆฌ์ ๋ฉ์ธ ๋๋ ๋ง์คํฐ ๋ธ๋์น์ ๋ฐ์ํ๋ฉด ๊นํ๋ธ์์ ์ํฌํ๋ก์ฐ๋ฅผ ๋ฑ๋กํฉ๋๋ค.
์๋ํ๋ธ ๊ด๋ จ ์ํฌ๋ฆฟ ์์ฑ
์๋ํ๋ธ ์ํฌํ๋ก์ฐ์์ ์ฌ์ฉํ๋ ๋๊ฐ์ง ์ํฌ๋ฆฟ์ ๊นํ๋ธ ๋ฆฌํ์งํ ๋ฆฌ์ ์ค์ ํด์ผํฉ๋๋ค.
- SONAR_HOST : ์๋ํ๋ธ ํธ์คํธ ์ฃผ์
- SONAR_TOKEN : ์๋ํ๋ธ์์ ๋ฐ๊ธํ ํ ํฐ ์ ๋ณด
์๋ํ๋ธ ์ํฌํ๋ก์ฐ ์คํ
์๋ํ๋ธ ์ํฌํ๋ก์ฐ ์ค์ ์ด ์๋ฃ๋์์ผ๋ฏ๋ก ๋ฉ์ธ ๋ธ๋์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์ํฌํ๋ก์ฐ๋ฅผ ์คํํฉ๋๋ค.
ํ๋ก์ ํธ ์ฝ๋์ ๋ํ ๋น๋๊ฐ ์ ์์ ์ผ๋ก ์ํ๋๊ณ ์๋ํ๋ธ ์๋ฒ๋ฅผ ํตํด ์ ์ ๋ถ์์ ์ํ๋์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ํฌํ๋ก์ฐ๊ฐ ์ ์์ ์ผ๋ก ์๋ฃ๋ฉ๋๋ค.
์ ์ ๋ถ์ ๊ฒฐ๊ณผ
์๋ํ๋ธ ์์คํ ์ ์ ์ํ์ฌ ์๋ํ๋ธ ์ํฌํ๋ก์ฐ๋ฅผ ์คํํ ํ๋ก์ ํธ์ ์ ์ ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํฉ๋๋ค.
๋น๋ ํ ์คํธ๋ ์ํํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง๋ ๋ถ์ํ ์ ์์์ผ๋ 10๊ฐ์ ์ฝ๋ ์ ์ทจ๊ฐ ๋ฐ๊ฒฌ๋์์ต๋๋ค.
์ฝ๋ ์ ์ทจ ๊ฒํ ๋ฐ ๊ฐ์
์ ์ ๋ถ์ ๊ฒฐ๊ณผ๋ก ๊ฒ์ถ๋ ์ฝ๋ ์ ์ทจ์ ๋ํ ๋ด์ฉ์ ๊ฒํ ํ๊ณ ์ด๋ฅผ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ฝ๋ ์ ์ทจ
์ฒซ๋ฒ์งธ ๊ฒ์ถ ํญ๋ชฉ์ ์ฐ์๋ ๋ผ์ธ์ ์ฃผ์์ผ๋ก ์ฒ๋ฆฌํ ๋ถ๋ถ์ ์ ๊ฑฐํด์ผํ๋ค๋ ๊ฒ์ ๋๋ค.
๋ง์ฝ, ์ด๋ ๊ฒ ์ฃผ์๋์ด์๋ ๊ฒ์ด ๋จ์์์ด์ผ ํ๋ค๊ณ ๊ฐ์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ๋ก์ ํธ์ ๋ํ ๊ฒ์ถ ๊ท์น์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
# Ignore Rules
sonar.issue.ignore.multicriteria=e1,e2
sonar.issue.ignore.multicriteria.e1.ruleKey=java:S125
sonar.issue.ignore.multicriteria.e1.resourceKey=**/*.java
sonar.issue.ignore.multicriteria.e2.ruleKey=java:S1192
sonar.issue.ignore.multicriteria.e2.resourceKey=**/*.java
java:S125๋ ๋ธ๋ก์ผ๋ก ๋ ์ฃผ์์ ๋จ๊ธฐ๊ณ ์๋ค๋ ์ ์ทจ์ด๋ฉฐ java:S1192๋ ๋์ผํ ๋ฌธ์์ด์ ์์๋ก ์ทจ๊ธํ์ง ์๋๋ค๋ ์ ์ทจ์ ๋๋ค. ์ ๋ ์ด๊ฒ์ ์ ์ทจ๋ก ๋ณด์ง ์๊ธฐ ์ํด์ ์์ ๊ฐ์ด ์ค์ ํ๊ณ ์๋ํ๋ธ ์ํฌํ๋ก์ฐ๋ฅผ ๋ค์ ์ํํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ์กด์ ๊ฒ์ถ๋์๋ ์ฝ๋ ์ ์ทจ ์ค java:S125์ java:S1192์ ํด๋นํ๋ ๋ถ๋ถ์ด ์ ์ธ๋์ด 3๊ฐ์ ์ฝ๋ ์ ์ทจ๊ฐ ์ค์ด๋ค์์์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ์ฌ ๋๋ ๊ฐ๋ฐํ์์ ํ๋ก์ ํธ ์ฝ๋์ ๋ํ ๊ท์น์ ๊ฒํ ํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผํฉ๋๋ค๋ง ์ ํฌ ํ์ฌ๋ ์ ์ ๊ทธ๋ฌ์ง ์๊ณ ์์ด ์์ฌ์์ด ๋ง์ต๋๋ค. ์ฒด๊ณ๊ฐ ์๋ค๋ณด๋ ๋ฌด์ธ๊ฐ ๋์ ์ ์ํ์ง๋ง ์ค์ ๋ก๋ ์ ๋๋ก ํ์ฉํ์ง ์๋๊ฒ ๋ง์ ๊ฒ ๊ฐ์์.
์๋ฌดํผ ๋๋จธ์ง ์ฝ๋ ์ ์ทจ์ ๋ํด์๋ ๋ฆฌํฉํ ๋ง์ ์ํํ์ฌ ์์ ๋ณด๋๋ก ํ๋ฉด์ ๋ง์น๊ฒ ์ต๋๋ค.
@SuppressWarnings
sonar-project.properties์์ ์ ์ธ๋๋๋ก ์ ์ํ ๊ท์น์ด ํจํด์ ์ํ ๊ฒ์ด๋ผ๋ฉด ํน์ ํด๋์ค ๋๋ ํจ์ ๋จ์๋ก ๊ท์น์ ์ ์ธํ๊ณ ์ถ์ ๊ฒฝ์ฐ @SuppressWarnings์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
@SuppressWarnings({"squid:S125","squid:S1192"})
@Configuration
public class SecurityConfig {}
๊ฐ์ฌํฉ๋๋ค.