Skip to content

SonarQube & JaCoCo

Minjeong Nam edited this page Oct 27, 2022 · 2 revisions

정적 분석 도구

정적분석도구는 소스 코드를 실행시키지 않고 코딩 표준 준수 여부, 코딩 스타일 적정 여부 등을 판단한다.

그 과정에서 코드내에서 발견할 수 있는 코드 스멜, 잠재적인 결함, 컨벤션 체크, 보안 취약점 등을 코드 레벨에서 분석해서 레포팅 해준는 점이 코드의 퀄리티를 높이는데에 많은 도움을 준다.

  정적 분석(static analysis) 동적 분석(dynamic analysis)
분석 대상 소스 코드 또는 컴파일된 코드 프로그램 실행 환경
테스트 범위 소스 코드의 모든 부분 실행 가능한 경로
활용 코드 상의 문제나 실수를 찾음 테스트, 모니터

종류

  • pmd
    • 미사용 변수, 비어있는 코드 블락, 불필요한 오브젝트 생성과 같은 Defect을 유발할 수 있는 코드를 검사
    • 주로 Java에서 사용하지만, Javascript, PLSQL, XML 등의 언어도 지원
  • checkstyle
    • 코드가 코딩 룰을 잘 따르고 있는지 분석
    • 디폴트 코딩룰: Google's Style, Unix Style
    • 조직만의 코딩 룰을 정의 가능
  • findbugs
    • 잠재적 버그를 찾기 위한 목적으로 사용.
    • 자바 소스파일이 아닌 바이트 코드를 이용함.
    • 바이트코드를 읽으므로 속도가 빠르고 정확성이 높은편임.
  • sonarqube
    • 중복코드, 복잡도, 코딩 설계 등을 분석하는 소스 분석 통합 플랫폼
    • 다른 정적 분석 도구에 비해 다양한 기능을 지원

왜 SonarQube인가?

  • 레퍼런스가 많다.
  • Github나 Jenkins와의 연동을 통해 자동 정적 코드 분석을 구성할 수 있다.
    • 다만, 우리는 Jenkins의 용량 문제 등이 있으므로 Jenkins가 아닌 Github action 과의 연동을 하는 것으로!
  • 장점들
    • 지속적인 인스펙션 : 지속적인 통합과 같이 빌드와 연동하여 지속적으로 코드에 대한 인스펙션을 수행합니다.
    • 품질 중앙화 : 개발된 조직의 코드의 품질을 중앙 저장소에서 가시화하고 단일 위치에서 관리합니다.
    • DevOps와의 통합 : 다양한 빌드 시스템, CI 엔진과 통합되어 DevOps 실천을 지원합니다.
    • 품질 요구사항 설정 : 품질 게이트를 통해 표준화된 코드 품질 요구사항을 설정합니다.
    • 플러그인을 통한 확장 : 다수의 플러그인을 통해 SonarQube의 기능을 확장할 수 있습니다.
    • 오픈소스 프로젝트 : 오픈소스 프로젝트로 특정 범위까지 무료로 사용 가능하다.

설치 및 사용 과정

ec2 인스턴스에 SonarQube 설치 및 실행

  • SonarQube 를 실행하기 위해서는 1.8 버전 이상의 자바가 필요하다.
// wget 으로 소나큐브 설치, 압축 해제(설치)

$ sudo wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.6.zip
$ sudo unzip sonarqube-7.6.zip
  • 기본 포트가 9000이므로 인스턴스 인바운드 규칙으로 인한 포트 변경
// /app/sonarqube/sonarqube-7.6/conf/sonar.properties 파일

...
sonar.web.port=8081
...

arm64 문제

SonarQube 측에서 arm64 환경의 버전을 공식적으로 지원하지 않기 때문에 Jar 파일을 직접 실행시키는 방식으로 우회해야한다. 관련 링크

$ cd /app/sonarqube/sonarqube-7.6/lib

$ java -jar sonar-application-7.6.jar

Github Actions 연동 설정

# Workflow 의 이름 설정
name: backend-sonarqube

# develop 브랜치에 대한 pr 이벤트가 일어났을 때 실행한다는 설정
on:
  push:
    branches: ["develop"]
    types : [ labeled ]
  pull_request:
    branches: ["develop", "main"]
    types : [ labeled ]

# job 의 공통된 옵션
defaults:
  run:
    # 작업을 수행할 디렉토리 설정
    working-directory: ./backend/reviewduck/

# 실행 해야 할 job 들에 대한 설정
jobs:
  # Job의 이름 설정, 빌드 수행, Scanner 발동
  analysis:
    # 라벨 설정
    if : ${{ github.event.label.name == 'back-end'}}
    # ubuntu 환경에서 실행, 환경은 GitHub 이 제공
    runs-on: ubuntu-latest
    # 현재 Job에서 사용할 환경변수, repository setting secrets 에서 설정한 환경변수 사용
    env:
      SONARQUBE_PROJECT_NAME: reviewDuck
      SONARQUBE_URL: ${{ secrets.SONAR_HOST_URL }}
      SONARQUBE_TOKEN: ${{ secrets.SONAR_TOKEN }}
      PR_NUMBER: ${{ github.event.pull_request.number }}
      clientId: ${{ secrets.CLIENTID }}
      clientSecret: ${{ secrets.CLIENTSECRET }}
      jwtKey: ${{ secrets.JWTKEY }}
      jwtRefreshKey: ${{ secrets.JWTREFRESHKEY }}
      jwtExpireLength: ${{ secrets.JWTEXPIRELENGTH }}
      jwtRefreshExpireLength: ${{ secrets.JWTREFRESHEXPIRELENGTH }}

    # analysis job 의 세부 단계 설정
    steps:
      # 소스코드 체크아웃 수행
      - name: Checkout source code
        uses: actions/checkout@v2
        with:
          token: ${{ secrets.SECURITY_TOKEN }}
          submodules: recursive

      # gradlw 파일 권한 변경
      - name: gradlew permission change
        run: sudo chmod 755 gradlew

      # 파일 빌드
      - name: Build with Gradle
        run: ./gradlew build
        env:
          clientId: ${{ secrets.CLIENTID }}
          clientSecret: ${{ secrets.CLIENTSECRET }}
          jwtKey: ${{ secrets.JWTKEY }}
          jwtRefreshKey: ${{ secrets.JWTREFRESHKEY }}
          jwtExpireLength: ${{ secrets.JWTEXPIRELENGTH }}
          jwtRefreshExpireLength: ${{ secrets.JWTREFRESHEXPIRELENGTH }}

      # Gralde 의 Scanner 발동, 위의 env 에서 선언한 환경변수와 함께 발동
      - name: Sonarqube Analysis
        run: ./gradlew test sonarqube
          -Dsonar.host.url=${{ env.SONARQUBE_URL }}
          -Dsonar.projectName=${{ env.SONARQUBE_PROJECT_NAME }}-${{ env.PR_NUMBER }}
          -Dsonar.login=${{ env.SONARQUBE_TOKEN }} --info

      # PR 에 Comment 를 달아주는 스크립트 실행
      - name: Comment Sonarqube URL
        uses: actions/github-script@v4
        with:
          script: |
            const { SONARQUBE_PROJECT_NAME, 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_NAME }-${ PR_NUMBER } 분석 결과 확인하기 [링크](${SONARQUBE_URL})`
            })
Clone this wiki locally