SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

SonarQube๋Š” ๊ด‘๋ฒ”์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๊ณ  ์ฝ”๋“œ ์ค‘๋ณต, ์ฝ”๋”ฉ ํ‘œ์ค€ ์ค€์ˆ˜, ํ…Œ์ŠคํŠธ ๋ฒ”์œ„, ์ฝ”๋“œ ๋ณต์žก์„ฑ, ์ž ์žฌ์  ๋ฒ„๊ทธ ๋“ฑ๊ณผ ๊ฐ™์€ ์ง€ํ‘œ์— ๋Œ€ํ•œ ๋ณด๊ณ ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๋ณด์ฆ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. SonarQube๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‹œ๊ฐํ™”ํ•˜๊ณ  ์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ ์—ญํ•™์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชฉํ‘œ: ๊ฐœ๋ฐœ์ž์—๊ฒŒ SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋‘ ๊ฐ€์ง€ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • SonarQube์—์„œ ์†Œ์Šค์ฝ”๋“œ ํ’ˆ์งˆ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ด ๋ณด์„ธ์š”. SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ๊ฐ€ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•˜๋ฉด ์–ด์…ˆ๋ธ”๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฉ”์ธ ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์— ์†Œ์Šค์ฝ”๋“œ ํ’ˆ์งˆ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

SonarQube ์„ค์น˜

rpm ํŒจํ‚ค์ง€์—์„œ sonarqube๋ฅผ ์„ค์น˜ํ•˜๋ ค๋ฉด ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. https://harbottle.gitlab.io/harbottle-main.

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 ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์˜ค๋žซ๋™์•ˆ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์šฐ๋ฆฌ๋งŒ์˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•ด ๋ด…์‹œ๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. https://github.com/uweplonus/spotbugs-examples.

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๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. http://172.26.9.115:9000/
์˜ˆ๋ฅผ ๋“ค์–ด "๋ฐฐ์ง€"์™€ ๊ฐ™์€ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
์ด ์‚ฌ์šฉ์ž๋กœ SonarQube์— ๋กœ๊ทธ์ธํ•˜์„ธ์š”.

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

"๋‚ด ๊ณ„์ •"์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์˜ˆ๋ฅผ ๋“ค์–ด "read_all_repository"๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ƒˆ ํ† ํฐ์„ ์ƒ์„ฑํ•˜๊ณ  "์ƒ์„ฑ"์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

ํ† ํฐ์ด ๋‚˜ํƒ€๋‚œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” ๋”ฑ 1๋ฒˆ๋งŒ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž๋กœ ๋กœ๊ทธ์ธํ•˜์„ธ์š”.

๊ตฌ์„ฑ -> SVG ๋ฐฐ์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

์ด ํ† ํฐ์„ "ํ™œ๋™ ๋ฐฐ์ง€ ํ† ํฐ" ํ•„๋“œ์— ๋ณต์‚ฌํ•˜๊ณ  ์ €์žฅ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์„ธ์š”.

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

๊ด€๋ฆฌ -> ๋ณด์•ˆ -> ๊ถŒํ•œ ํ…œํ”Œ๋ฆฟ -> ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ(๋ฐ ๊ธฐํƒ€ ํ…œํ”Œ๋ฆฟ)์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐ์ง€ ์‚ฌ์šฉ์ž๋Š” "์ฐพ์•„๋ณด๊ธฐ" ํ™•์ธ๋ž€์„ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ.

์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. https://github.com/jitpack/maven-simple.

์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ .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์—์„œ ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

README.md์— ๊ฐ€๋ฐฉ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

๋ฐฐ์ง€ ํ‘œ์‹œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SonarQube์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

๋ฐฐ์ง€ ํ‘œ์‹œ ๋ฌธ์ž์—ด ๊ตฌ๋ฌธ ๋ถ„์„:

[![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์˜ ์†Œ์Šค ์ฝ”๋“œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ์ƒํƒœ๋ฅผ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ํ‘œ์‹œ

์ธก์ •ํ•ญ๋ชฉ์„ ์–ป๊ธฐ ์œ„ํ•œ ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋ฅผ ๋ด.

๊ฐœ์„ , ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์œ„ํ•œ ๋ชจ๋“  ํ’€ ์š”์ฒญ ์ด ์ €์žฅ์†Œ์— ์ œ์ถœ.

SonarQube์— ๋Œ€ํ•œ ํ…”๋ ˆ๊ทธ๋žจ ์ฑ„ํŒ… https://t.me/sonarqube_ru
DevSecOps์— ๋Œ€ํ•œ ์ „๋ณด ์ฑ„ํŒ… - ๋ณด์•ˆ DevOps https://t.me/sec_devops

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€