SonarQube๋ ๊ด๋ฒ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ง์ํ๊ณ ์ฝ๋ ์ค๋ณต, ์ฝ๋ฉ ํ์ค ์ค์, ํ ์คํธ ๋ฒ์, ์ฝ๋ ๋ณต์ก์ฑ, ์ ์ฌ์ ๋ฒ๊ทธ ๋ฑ๊ณผ ๊ฐ์ ์งํ์ ๋ํ ๋ณด๊ณ ๋ฅผ ์ ๊ณตํ๋ ์คํ ์์ค ์ฝ๋ ํ์ง ๋ณด์ฆ ํ๋ซํผ์ ๋๋ค. SonarQube๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ํธ๋ฆฌํ๊ฒ ์๊ฐํํ๊ณ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ํ๋ก์ ํธ ๊ฐ๋ฐ ์ญํ์ ์ถ์ ํ ์ ์์ต๋๋ค.
๋ชฉํ: ๊ฐ๋ฐ์์๊ฒ SonarQube์ ์์ค ์ฝ๋ ํ์ง ๊ด๋ฆฌ ์ํ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
๋ ๊ฐ์ง ์๋ฃจ์ ์ด ์์ต๋๋ค.
- SonarQube์์ ์์ค์ฝ๋ ํ์ง๊ด๋ฆฌ ์ํ๋ฅผ ํ์ธํ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํด ๋ณด์ธ์. SonarQube์ ์์ค ์ฝ๋ ํ์ง ๊ด๋ฆฌ๊ฐ ํต๊ณผํ์ง ๋ชปํ๋ฉด ์ด์ ๋ธ๋ฆฌ๊ฐ ์คํจํ๊ฒ ๋ฉ๋๋ค.
- ๋ฉ์ธ ํ๋ก์ ํธ ํ์ด์ง์ ์์ค์ฝ๋ ํ์ง๊ด๋ฆฌ ์ํ๋ฅผ ํ์ํฉ๋๋ค.
SonarQube ์ค์น
rpm ํจํค์ง์์ sonarqube๋ฅผ ์ค์นํ๋ ค๋ฉด ์ ์ฅ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
CentOS 7์ฉ ์ ์ฅ์๊ฐ ํฌํจ๋ ํจํค์ง๋ฅผ ์ค์นํด ๋ณด๊ฒ ์ต๋๋ค.
yum install -y https://harbottle.gitlab.io/harbottle-main/7/x86_64/harbottle-main-release.rpm
Sonarqube ์์ฒด๋ฅผ ์ค์นํฉ๋๋ค.
yum install -y sonarqube
์ค์นํ๋ ๋์ ๋๋ถ๋ถ์ ํ๋ฌ๊ทธ์ธ์ด ์ค์น๋์ง๋ง findbugs ๋ฐ pmd๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค.
yum install -y sonarqube-findbugs sonarqube-pmd
์๋น์ค๋ฅผ ์์ํ๊ณ ์์์ ์ถ๊ฐํ์ธ์.
systemctl start sonarqube
systemctl enable sonarqube
๋ก๋ํ๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ฉด sonar.web.javaOpts ์ต์ ๋์ ๋์ ์์ฑ๊ธฐ /dev/./urandom์ ์ถ๊ฐํ์ธ์.
sonar.web.javaOpts=ะดััะณะธะต ะฟะฐัะฐะผะตััั -Djava.security.egd=file:/dev/urandom
SonarQube์์ ์์ค ์ฝ๋ ํ์ง ๊ด๋ฆฌ ์ํ๋ฅผ ํ์ธํ๊ธฐ ์ํ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํฉ๋๋ค.
๋ถํํ๊ฒ๋ sonar-break-maven-plugin ํ๋ฌ๊ทธ์ธ์ ์ค๋ซ๋์ ์ ๋ฐ์ดํธ๋์ง ์์์ต๋๋ค. ๊ทธ๋ผ ์ฐ๋ฆฌ๋ง์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด ๋ด ์๋ค.
ํ
์คํธ๋ฅผ ์ํด ์ ์ฅ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Gitlab์ผ๋ก ๊ฐ์ ธ์ค๋ ์ค์ ๋๋ค. .gitlab-ci.yml ํ์ผ์ ์ถ๊ฐํฉ๋๋ค.
variables:
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=~/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
SONAR_HOST_URL: "http://172.26.9.226:9000"
LOGIN: "admin" # ะปะพะณะธะฝ sonarqube
PASSWORD: "admin" # ะฟะฐัะพะปั sonarqube
cache:
paths:
- .m2/repository
build:
image: maven:3.3.9-jdk-8
stage: build
script:
- apt install -y jq || true
- mvn $MAVEN_CLI_OPTS -Dmaven.test.failure.ignore=true org.jacoco:jacoco-maven-plugin:0.8.5:prepare-agent clean verify org.jacoco:jacoco-maven-plugin:0.8.5:report
- mvn $MAVEN_CLI_OPTS -Dmaven.test.skip=true verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$LOGIN -Dsonar.password=$PASSWORD -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
- export URL=$(cat target/sonar/report-task.txt | grep ceTaskUrl | cut -c11- ) #URL where report gets stored
- echo $URL
- |
while : ;do
curl -k -u "$LOGIN":"$PASSWORD" "$URL" -o analysis.txt
export status=$(cat analysis.txt | jq -r '.task.status') #Status as SUCCESS, CANCELED, IN_PROGRESS or FAILED
echo $status
if [ ${status} == "SUCCESS" ];then
echo "SONAR ANALYSIS SUCCESS";
break
fi
sleep 5
done
- curl -k -u "$LOGIN":"$PASSWORD" "$URL" -o analysis.txt
- export status=$(cat analysis.txt | jq -r '.task.status') #Status as SUCCESS, CANCELED or FAILED
- export analysisId=$(cat analysis.txt | jq -r '.task.analysisId') #Get the analysis Id
- |
if [ "$status" == "SUCCESS" ]; then
echo -e "SONAR ANALYSIS SUCCESSFUL...ANALYSING RESULTS";
curl -k -u "$LOGIN":"$PASSWORD" "$SONAR_HOST_URL/api/qualitygates/project_status?analysisId=$analysisId" -o result.txt; #Analysis result like critical, major and minor issues
export result=$(cat result.txt | jq -r '.projectStatus.status');
if [ "$result" == "ERROR" ];then
echo -e "91mSONAR RESULTS FAILED";
echo "$(cat result.txt | jq -r '.projectStatus.conditions')"; #prints the critical, major and minor violations
exit 1 #breaks the build for violations
else
echo -e "SONAR RESULTS SUCCESSFUL";
echo "$(cat result.txt | jq -r '.projectStatus.conditions')";
exit 0
fi
else
echo -e "e[91mSONAR ANALYSIS FAILEDe[0m";
exit 1 #breaks the build for failure in Step2
fi
tags:
- docker
.gitlab-ci.yml ํ์ผ์ ์๋ฒฝํ์ง ์์ต๋๋ค. Sonarqube์ ์ค์บ ์์ ์ด "SUCCESS" ์ํ๋ก ์ข ๋ฃ๋์๋์ง ํ ์คํธํ์ต๋๋ค. ์ง๊ธ๊น์ง ๋ค๋ฅธ ์ํ๋ ์์์ต๋๋ค. ๋ค๋ฅธ ์ํ๊ฐ ๋ฐ์ํ๋ ๋๋ก ์ด ๊ฒ์๋ฌผ์์ .gitlab-ci.yml์ ์์ ํ๊ฒ ์ต๋๋ค.
๋ฉ์ธ ํ๋ก์ ํธ ํ์ด์ง์ ์์ค์ฝ๋ ํ์ง๊ด๋ฆฌ ํํฉ ํ์
SonarQube์ฉ ํ๋ฌ๊ทธ์ธ ์ค์น
yum install -y sonarqube-qualinsight-badges
์ฐ๋ฆฌ๋ SonarQube๋ก ์ด๋ํฉ๋๋ค.
์๋ฅผ ๋ค์ด "๋ฐฐ์ง"์ ๊ฐ์ ์ผ๋ฐ ์ฌ์ฉ์๋ฅผ ๋ง๋ญ๋๋ค.
์ด ์ฌ์ฉ์๋ก SonarQube์ ๋ก๊ทธ์ธํ์ธ์.
"๋ด ๊ณ์ "์ผ๋ก ์ด๋ํ์ฌ ์๋ฅผ ๋ค์ด "read_all_repository"๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ํ ํฐ์ ์์ฑํ๊ณ "์์ฑ"์ ํด๋ฆญํฉ๋๋ค.
ํ ํฐ์ด ๋ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๋ ๋ฑ 1๋ฒ๋ง ๋ฑ์ฅํฉ๋๋ค.
๊ด๋ฆฌ์๋ก ๋ก๊ทธ์ธํ์ธ์.
๊ตฌ์ฑ -> SVG ๋ฐฐ์ง๋ก ์ด๋ํฉ๋๋ค.
์ด ํ ํฐ์ "ํ๋ ๋ฐฐ์ง ํ ํฐ" ํ๋์ ๋ณต์ฌํ๊ณ ์ ์ฅ ๋ฒํผ์ ํด๋ฆญํ์ธ์.
๊ด๋ฆฌ -> ๋ณด์ -> ๊ถํ ํ ํ๋ฆฟ -> ๊ธฐ๋ณธ ํ ํ๋ฆฟ(๋ฐ ๊ธฐํ ํ ํ๋ฆฟ)์ผ๋ก ์ด๋ํฉ๋๋ค.
๋ฐฐ์ง ์ฌ์ฉ์๋ "์ฐพ์๋ณด๊ธฐ" ํ์ธ๋์ ์ ํํด์ผ ํฉ๋๋ค.
ํ ์คํธ.
์๋ฅผ ๋ค์ด ํ๋ก์ ํธ๋ฅผ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
์ด ํ๋ก์ ํธ๋ฅผ ๊ฐ์ ธ์ค๊ฒ ์ต๋๋ค.
๋ค์ ๋ด์ฉ์ผ๋ก .gitlab-ci.yml ํ์ผ์ ํ๋ก์ ํธ ๋ฃจํธ์ ์ถ๊ฐํฉ๋๋ค.
variables:
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=~/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
SONAR_HOST_URL: "http://172.26.9.115:9000"
LOGIN: "admin" # ะปะพะณะธะฝ sonarqube
PASSWORD: "admin" # ะฟะฐัะพะปั sonarqube
cache:
paths:
- .m2/repository
build:
image: maven:3.3.9-jdk-8
stage: build
script:
- mvn $MAVEN_CLI_OPTS -Dmaven.test.failure.ignore=true org.jacoco:jacoco-maven-plugin:0.8.5:prepare-agent clean verify org.jacoco:jacoco-maven-plugin:0.8.5:report
- mvn $MAVEN_CLI_OPTS -Dmaven.test.skip=true verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$LOGIN -Dsonar.password=$PASSWORD -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
tags:
- docker
SonarQube์์ ํ๋ก์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
README.md์ ๊ฐ๋ฐฉ์ ์ถ๊ฐํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ๊ฒ์ ๋๋ค:
๋ฐฐ์ง ํ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ฐฐ์ง ํ์ ๋ฌธ์์ด ๊ตฌ๋ฌธ ๋ถ์:
[![Quality Gate](http://172.26.9.115:9000/api/badges/gate?key=com.github.jitpack:maven-simple)](http://172.26.9.115:9000/dashboard?id=com.github.jitpack%3Amaven-simple)
[![ะะฐะทะฒะฐะฝะธะต](http://172.26.9.115:9000/api/badges/gate?key=Project Key)](http://172.26.9.115:9000/dashboard?id=id-ะฟัะพะตะบัะฐ)
[![Coverage](http://172.26.9.115:9000/api/badges/measure?key=com.github.jitpack:maven-simple&metric=coverage)](http://172.26.9.115:9000/dashboard?id=com.github.jitpack%3Amaven-simple)
[![ะะฐะทะฒะฐะฝะธะต ะะตััะธะบะธ](http://172.26.9.115:9000/api/badges/measure?key=Project Key&metric=ะะะขะ ะะะ)](http://172.26.9.115:9000/dashboard?id=id-ะฟัะพะตะบัะฐ)
ํ๋ก์ ํธ ํค์ ํ๋ก์ ํธ ID๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ํ์ธํ ์ ์๋ ์์น์ ๋๋ค.
ํ๋ก์ ํธ ํค๋ ์ค๋ฅธ์ชฝ ํ๋จ์ ์์ต๋๋ค. URL์๋ ํ๋ก์ ํธ ID๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
์ธก์ ํญ๋ชฉ์ ์ป๊ธฐ ์ํ ์ต์
์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ฐ์ , ๋ฒ๊ทธ ์์ ์ ์ํ ๋ชจ๋ ํ ์์ฒญ
SonarQube์ ๋ํ ํ
๋ ๊ทธ๋จ ์ฑํ
DevSecOps์ ๋ํ ์ ๋ณด ์ฑํ
- ๋ณด์ DevOps
์ถ์ฒ : habr.com