프로젝트에서 팀장 역할을 담당하면서 개발 효율성과 배포 안정성을 높이기 위해 CI/CD 구성을 했습니다. 여러 CI/CD 도구들이 있지만 github과 간편한 설정으로 빠른 적용을 할 수 있으므로 GitHub Actions를 활용했습니다. 이를 통해서 CI/CD를 사용하는 이유에 대해 알아보고 GitHub Actions를 활용해서 CI/CD 구성한 부분에 대해 정리하는 포스팅입니다.
CI/CD 란
CI/CD는 소프트웨어 개발에서 지속적인 통합(Continuous Integration)과 지속적인 배포(Continuous Deployment)를 의미합니다. 개발과 배포 과정을 자동화하여 효율성을 높이고 오류를 줄이며 빠른 피드백을 제공하는 목적이 있습니다.
지속적 통합(CI)은 개발 코드를 자주 통합하고 코드 변경 사항이 발생할 때마다 자동으로 빌드 및 테스트를 실행하여 이로 인해 버그와 충돌을 미리 발견하여 최소화 할 수 있습니다.
지속적 배포(CD)는 테스트와 승인을 거친 코드를 자동으로 프로덕션 환경에 배포하여 새로운 기능과 버그 수정 사항을 빠르게 사용자에게 제공하고 제품 개선 속도를 높일 수 있습니다.
파이프라인은 개발에서 자동화된 일련의 과정을 의미하며 코드 변경 사항을 자동으로 빌드, 테스트, 배포하는 작업 흐름을 말합니다. 목적으로 자동화와 일관성을 유지하며 수동 작업을 줄이고 코드 처리 및 배포 과정을 효율적으로 관리할 수 있게 돕습니다.
즉 CI/CD 파이프라인의 핵심은 코드 변경 사항을 자동으로 테스트하고 빌드한 후 안정적으로 배포하여 코드 품질을 유지하고 빠르고 효율적인 배포를 하는 것입니다.
Github Actions
프로젝트 루트에 .github/workflows 폴더 만들고 여기에 워크플로우 정의가 포함된 .yaml 파일을 생성합니다. (아래 demo.yml은 github actions 공식문서 예시 참고)
// ex) .github/workflows
project/
├── .github/
│ └── workflows/
│ ├── github-actions-demo.yml
│ └── deploy.yml
// ex) github actions demo.yml
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
프로젝트에서 Jest를 활용하여 단위 테스트를 통해 코드의 기능을 검증하고 있습니다.
또한 코드 변경 사항에 대해 자동으로 테스트 커버리지 리포트를 생성하고 Codecov와 연동하여 커버리지 범위를 분석하며 부족한 부분을 파악합니다. 이를 통해 테스트 커버리지를 자동화하고 품질을 높일 수 있으므로 설정했습니다.
Codecov 테스트 커버리지 측정 및 자동화 정리 포스팅
팀 프로젝트 진행을 위해 Organization을 생성해서 진행했습니다.
하지만 Organization 팀 레포에서 vercel로 배포를 하려면 유료인 프로 계정으로 배포해야만 합니다. 처음에 프로 계정으로 2주간 무료 체험이 가능하지만 큰 의미가 없었습니다.
그래서 Organization 팀 레포에서 무료로 배포 할 수 있는 부분을 구글링 하면 나오는 방법이 개인 레포로 fork하는 방법으로써 세부적인 방식은 아래와 같이 2가지로 나눌 수 있습니다.
1) 팀 레포에서 변경사항이 있으면 fork된 레포에서 sync fork 클릭을 통해 수동으로 원본인 팀 레포의 변경사항을 가져와 동기화 하기
2) GitHub Actions를 사용하여 자동 동기화 워크플로우를 설정 하기
2가지 방식 공통으로 팀 레포를 개인 레포로 fork를 해서 fork한 레포를 vercel에 연결하는 방법이지만 위처럼 수동이냐 자동이냐의 세부적인 차이가 있습니다.
원본인 팀 레포에서 변경사항이 있을경우 매번 fork된 레포가서 수동으로 동기화를 해주는 부분은 동기화를 실수로 잊어버리고 놓쳐버릴 가능성이 있기 때문에 관리적인 면에서 효율적이지 않다고 생각되었습니다.
그래서 GitHub Actions를 활용해서 자동 동기화 워크플로우를 설정을 했습니다.
먼저 Organization 레포를 fork 해주고 vercel에 fork한 레포를 연동한 상태에서 시작합니다.
1) secret token 발급

2) build.sh 파일 파일 생성
!/bin/sh
cd ../
mkdir output
cp -R ./team-repo-name/* ./output
cp -R ./output ./team-repo-name/
3) secret 등록

4) deploy yml 작성
// github/workflows/push-deploy.yml
name: git push into another repo to deploy to vercel
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
container: pandoc/latex
steps:
- uses: actions/checkout@v4
- name: Install mustache (to update the date)
run: apk add ruby && gem install mustache
- name: creates output
run: sh ./build.sh
- name: Pushes to another repository
id: push_directory
uses: cpina/github-action-push-to-another-repository@main
env:
API_TOKEN_GITHUB: ${{ secrets.MOMOIM_SECRET_KEY }}
with:
source-directory: "output"
destination-github-username: (본인의 github 계정 이름)
destination-repository-name: (배포한 레포 이름)
user-email: ${{ secrets.EMAIL }}
commit-message: ${{ github.event.commits[0].message }}
target-branch: main
- name: Test get variable exported by push-to-another-repository
run: echo $DESTINATION_CLONED_DIRECTORY

Organization에서 작성한 코드를 main 브랜치로 병합하면 Actions 탭에서 자동 배포 과정을 확인할 수 있습니다.