목차
- 개요
- 시나리오 소개
- 사전 작업 구성
- 워크플로우 구성
- 마치며
1. 개요
Github Actions를 이용하여 CI/CD 파이프라인 구성에 대한 이해를 해보려고 한다.
Github Actions는 Github 레포지토리를 이용해 간단하게 설정하고 사용하기 쉽다. 별도의 서버나 외부서비스를 구축할 필요 없이 Github에서 제공하는 기능으로 CI를 실행할 수 있기에 Github Actions를 선택하였다.
2. 시나리오 소개
요구사항
- 특정 path 에 대해서만 실행 (multi-board에 src/**)
- main branch로 PR이 생성 & 동기화 될 때 테스트 작업 실행 (CI)
- PR이 main으로 merge 되면 배포 (CD)
- 배포 성공 여부 슬랙으로 전송
위에 요구사항을 반영한 대략적인 플로우는 다음과 같다.
- main branch에서 분기된 feature branch 에서 commit 을 하고 업데이트 한다.
- src/** 내에 파일이 변경되거나 업데이트 한다.
- feature branch가 main branch로 PR을 만들면 CI를 수행한다.
- CI 프로세스가 성공한 다음 배포를 위한 PR을 merge 하면 개발 환경에 배포한다.
3. 사전 작업 구성
<워크 플로우 권한 범위 변경>
Repository에 Settings에 들어가 Actions > General 탭에 들어간다.
Workflow permissions을 Read and write permissions으로 변경한다.
<Github Personal Access Token 생성>
Settings > Developer Settings > Personal access tokens > Tokens (classic)
Note에 해당 토큰 네임을 작성해주고 Expiration 과 해당하는 Select scopes를 선택해서 생성해준다.
생성하면 다음과 같이 secret 값이 나오는데 이 값을 따로 저장해두면 된다.(다시 확인할 수 없기 때문에 꼭 저장해주자.)
이후에 Github actions 가 사용할 Github 권한을 이 Token을 이용해서 받아오게 된다.
<Slack Webhook>
Slack을 사용하는 이유는 Github actions이 Slack으로 메세지를 보내기 위해 아래와 같은 과정을 해준다.
https://api.slack.com/messaging/webhooks
해당 페이지를 들어가서 확인해보자.
Your Apps 에 들어가 Create New App 을 클릭한다.
다음과 같은 화면이 나오는데 From a manifest 클릭
해당 워크스페이스 설정하고 Next 클릭.
Features > Incoming Webhooks 에 들어가 활성화 시켜준다.
메세지를 받을 채널을 다음과 같이 만들어준다.
Add New Webhook to Workspace 를 클릭하여 방금 만든 워크스페이스를 액세스 하기 위한 권한을 설정해준다.
이전에 만든 github-actions 채널을 선택해준다.
Allow를 클릭하면 모든 사전 과정이 완료된다.
테스트를 위해 다음과 같은 내용을 복사해서 command에 넣어 사용해준다.
OK를 확인하고 슬랙 해당 채널에 Hello World 메세지가 출력된 것을 확인할 수 있다.
<SonarCloud와 Github Repository 연동하기>
SonarCloud 로그인
Analyze new project 클릭
Select repositories 를 통해 해당 프로젝트를 추가하고 Save 해준다.
해당 프로젝트 선택후 Set up 클릭.
Previous version 선택 후 Create project 클릭
프로젝트가 생성되면 현재 소스를 분석해서 보여준다.
Automatic Analysis 끄기
4. 워크플로우 구성
Github Actions workflow를 작성해 CI 작업 SonarCloud 연동, 배포 성공여부 슬랙 전송을 구성해보자.
name: CI/CD Pipeline
on:
pull_request:
types: [opened, synchronize, closed]
branches: [main]
paths:
- 'src/**'
push:
branches:
- main
jobs:
# CI & SonarCloud Analysis
sonarcloud:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'
cache: 'gradle'
- name: Cache SonarCloud packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build & SonarCloud Analysis
id: build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew build sonar --info
- name: Notify Build Status
if: always()
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "SonarCloud Build Status: *${{ job.status }}* for PR #${{ github.event.number }} on branch `${{ github.ref_name }}`."
}
# Deployment job after merge
deploy:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'
cache: 'gradle'
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build for Deployment
run: ./gradlew build --info
- name: Deploy Application
id: deploy
env:
DEPLOY_ENV: production
run: |
# Add your deployment script here
echo "Deploying application to $DEPLOY_ENV"
# Example: ./deploy.sh --env $DEPLOY_ENV
- name: Notify Deployment Status
if: always()
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "Deployment Status: *${{ job.status }}* for branch `${{ github.ref_name }}`."
}
현재 job 을 크게 sonarcloud와 deploy로 나누었지만, CI & SonarCloud Analysis만 이용하여 sonarcloud job만 사용해서 진행중이다.
만약, 추가 job을 이용해 aws나 docker와 같이 이용하면 해당 내용을 알맞게 수정해주면 된다.
sonarcloud job이 잘 수행 되었는지 확인해보자.
main branch에서 분기된 multi-board-13 branch가 commit 을 하고 업데이트 하여 PR을 날렸다.
PR이 생성되면서 해당 sonarcloud 잡이 잘 동작하는 확인.
main branch로 PR이 열렸을때 sonar cloud 에 코멘트가 달리는지 확인.
Slack 채널에 Build 성공 여부 메세지 출력 확인.
5. 마치며
Github actions을 통해 sonar cloud와 slack을 연동하고 빌드의 성공 여부를 자동으로 Slack 알림을 받을 수 있게 되었다.
이처럼 소나 클라우드를 사용해 예상치 못한 에러나 버그가 발생할 수 있는 경우를 알려주고 신뢰성을 높여주는 점에서 굉장히 좋은 정적 분석 도구라 생각한다.
쿠팡에서도 기술블로그에 소나큐브를 사용하여 코드 품질을 높이는 노력을 하고 있다고 한다. (https://medium.com/coupang-engineering/coupang-android-architecture-part-1-10be2ce231ac)
정적 분석이 에러나 버그를 잡는데 절대적이지는 않다. 하지만 이런 도구를 어떻게 사용하냐에 따라 강력한 도구가 될 수도, 쓸모가 없을 수 도 있기에 익숙해져서 유용하게 사용되었으면 한다. sonar qube, github actions 등을 이용하여 다양한 자동화 작업을 수행할 수 있는데 더 많은 활용 방법을 찾아서 유용하게 사용해보려 한다.
이번 스프린트를 진행하면서 생각보다 전체적으로 꽤나 많은 시간이 소요 되었다. 이 다음에는 Github actions를 이용해 AWS EC2에 배포를 해보려고 한다.
'Etc.' 카테고리의 다른 글
파일마다 EOL(EndOfLine) 넣어야 하는 이유는 무엇일까? (2) | 2024.11.29 |
---|---|
Github 저장소에 Repository Rule 제약하기 (0) | 2024.11.22 |
브라우저에 URL을 입력하면 어떤 일이 벌어질까? (0) | 2024.03.26 |
대용량 트래픽 처리를 위한 경매 기능 최적화 (0) | 2024.03.20 |
RabbitMQ 메세지큐 적용으로 성능 개선하기 (0) | 2024.03.19 |