들어가며
사이드 프로젝트에서 푸시 알림을 활용한 서비스를 개발하고 있습니다. CI 프로세스를 구축하는 과정에서 안정적인 통합을 위해 통합 이전에 테스트 코드를 자동으로 실행했습니다. 하지만 홀로 코드를 작성하다 보니, 컨벤션은 제대로 지켰는데, 작성한 코드가 보안적으로 취약점은 없는지 확인하기 힘들었습니다. 이때 코드를 정적으로 분석할 수 있는 SonarCloud를 적용한다면 안정적인 CI 프로세스를 구축할 수 있다고 생각했습니다. 이 글은 SonarCloud를 적용하기 위해 노력하며 작성됐고, 인프런 개발자 이동욱 님의 SonarCloud를 통한 Node.js & Jest 프로젝트 정적 분석하기 글과 SonarLint와 SonarCloud 연동하기 블로그 글을 참고했습니다.
SonarCloud
SonarCloud를 적용하면 정적 코드 분석이 가능합니다. SonarCloud를 통해 코드 스멜, 잠재적인 결함, 컨벤션 체크, 보안 취약점을 확인할 수 있습니다.
SonarCloud 활용하기
지금부터 SonarCloud를 적용해보겠습니다.
Open Source Projects일 경우 SonarCloud를 무료로 사용할 수 있기에, 프로젝트를 개발하면서 이 부분을 적용하려고 노력했습니다. SonarCloud을 연동하는 과정을 살펴보겠습니다.
먼저 연동을 위해 우측 상단에 있는 Log in 버튼을 클릭합니다.
저는 Github을 활용하기에, With GitHub 버튼을 클릭하여 로그인을 합니다.
회원가입이 완료되면 Create new organization을 클릭하고, Github 저장소들을 SonarCloud Organization으로 import 시킵니다.
제가 분석할 저장소는 triple 프로젝트이기 때문에, 이를 선택하고 Set Up 합니다.
이렇게 설정하면 자동으로 코드를 분석해줍니다. 위의 분석 결과를 보면 COVERAGE는 출력되지 않았습니다. 이는 자동 분석을 통해 저장소를 분석했기 때문에 나오지 않았습니다. 수동으로 분석한다면 커버리지가 나오는데, 커버리지 출력을 위해 설정을 해보겠습니다.
테스트 커버리지 측정하기
커버리지 측정을 위해 수동으로 분석하는 방법인 Github Action을 활용해야 합니다. Github Action에서 SonarCloud 접근을 할 수 있도록 SonarCloud Token 발급이 필요합니다.
My Account -> Security로 이동하면 Token 발급 페이지가 보입니다.
위와 같이 Token을 발급받고, Github 저장소의 secret에 등록합니다.
저는 Github Action에 SONAR_TOKEN이라는 이름으로 설정했습니다. 설정한 환경 변수는 Github Action에서 사용됩니다.
그 후 Administration의 Analysis Method로 들어가서 SonarCloud Automatic Analysis를 OFF로 설정합니다.
name: Integration Test
on:
pull_request:
branches:
- 'master'
jobs:
ci:
runs-on: ubuntu-latest
container: node:16-alpine
env:
NODE_ENV: CI
PORT: ${{ secrets.PORT }}
services:
rdb:
image: bitnami/mysql:8.0.20
env:
MYSQL_ROOT_PASSWORD: triplepassword
MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password
ports:
- 3306/tcp
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Install RDB Dependencies
run: apk add mysql-client
- name: Setup Node Environment
run: npm ci --force
- name: Test with DB
run: npx jest --coverage --runInBand --forceExit
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Success
run: echo Test Completed Successfully.
그 후 프로젝트에서 실행하는 workflow yml에 SonarCloud Scan이란 이름으로 추가했습니다.
// sonar-project.properties
sonar.projectKey=epitone_triple
sonar.organization=epitone
sonar.sources=apps,libs
# sonar.tests=apps,libs
# sonar.test.inclusions=apps/**/test,libs/**/test
sonar.javascript.lcov.reportPaths=./coverage/lcov.info
또한 sonar-project.properties 파일을 생성해서 SonarCloud가 프로젝트를 분석할 수 있도록 설정했습니다. sonar.javascript.lcov.reportPaths의 경우 jest --coverage를 통해 생성되는 리포트가 있는 위치입니다. 또한 sonar.projectKey와 sonar.organization은 Information에 들어가면 확인할 수 있습니다. 아래 페이지에서 확인이 가능합니다.
SonarCloud는 직접 커버리지를 분석하는 것이 아닌, 테스트 프레임워크의 커버리지 결과물을 활용하기에, 꼭 해당 커버리지 리포트가 지정된 곳에 생성되어야 합니다. 이를 위해 아래와 같이 jest 설정을 진행합니다.
"jest": {
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "./coverage",
}
sonar-project.properties에 지정된 sonar.javascript.lcov.reportPaths의 디렉터리 주소를 등록합니다. 커버리지 파일명이 lcov.info이기 때문에 그 앞 path까지만 등록합니다. 위 설정이 마무리됐다면 저장소 Push를 통해 Github Action이 잘 동작하는지 확인하겠습니다.
PR을 올리면, 리포트 결과를 확인할 수 있습니다.
만약 처음 SonarCloud를 설정했다면 위의 링크를 보시면 더욱 자세하게 내용을 살펴보실 수 있습니다.
VSCode에 SonarLint 적용하기
SonarCloud를 적용하면 아래 내용처럼 Bugs와 Code Smells 등을 확인할 수 있습니다.
하지만 코드 문제를 확인하려면 Github Actions을 통해서 확인할 수 있습니다. IDE에서 바로 확인할 수 있다면 미리 코드 문제를 확인할 수 있다는 장점이 있으니, 빠르게 문제를 해결할 수 있습니다. 아래에서는 VSCode를 통해 SonarLint를 적용하는 방법을 알아보겠습니다.
SonarLint 플러그인 설치
SonarLint을 VSCode에서 활용하기 위해 아래와 같이 플러그인을 설치합니다.
그 후 Mac을 활용한다면 Command + Shift + p을 입력 후 sonarCloud을 연결합니다.
그럼 위와 같은 설정을 볼 수 있습니다. 저는 현재 SonarCloud를 활용하고 있기에 좌측 하단에서 Add SonarCloud Connection을 클릭합니다.
그 후 User Token과 Organization Key, Connection Name을 입력하는 칸이 나옵니다. 이는 위에서 테스트 커버리지 확인을 위해 Token을 생성했던 것처럼, 새로운 토큰 하나를 만듭니다.
My Account -> Security로 이동해서 Token 발급 페이지로 이동하고
새로운 토큰을 생성합니다.
Organization Key와 Connection Name은 위의 Organization Key를 모두 입력했습니다.
그렇게 모두 입력했으면 위처럼 Lint 설정이 보이는 것을 확인할 수 있습니다. 이를 통해 로컬 환경에서도 SonarLint를 활용할 수 있게 되었습니다.
마치며
앞으로도 팀의 발전을 돕는 개발자가 되기 위해 노력하려 합니다. 팀에 필요한 부분이 무엇일지 고민하면서, 팀에 도움이 된다면, 열심히 공부해서 실무에 적용할 수 있는 개발자가 되기 위해 노력하고 싶습니다. 팀의 성장에 기여할 수 있는 개발자가 되겠습니다.
참고 및 출처
'Project > 서버 개발' 카테고리의 다른 글
[Project] 프로젝트 삽질기38 (feat AWS SQS 적용) (2) | 2022.07.15 |
---|---|
[Project] 프로젝트 삽질기37 (feat AWS SQS) (0) | 2022.07.15 |
[Project] 프로젝트 삽질기35 (feat CI) (0) | 2022.07.10 |
[Project] 프로젝트 삽질기34 (feat AWS EB, Docker) (0) | 2022.07.10 |
[Project] 프로젝트 삽질기33 (feat 정적 팩토리 메서드) (2) | 2022.07.09 |