
GitHub Actions로 시작하는 완벽한 CI/CD 파이프라인 자동화
- DevOps, Development
- 24 Jun, 2024
수동 배포의 악몽에서 벗어나기
"자, 이제 코딩 끝! 서버에 접속해서 git pull 받고, 의존성 다시 설치하고, 빌드하고, 기존 프로세스 죽이고, 새 프로세스 띄우자."
프로젝트 초기에는 이러한 수동 배포 과정이 크게 번거롭지 않을 수 있습니다. 하지만 서비스가 커지고 팀원이 늘어나면서 하루에도 수십 번씩 코드가 통합되고 배포되어야 한다면 어떨까요? 사람이 매번 수동으로 테스트하고 서버에 접속하여 스크립트를 치는 과정은 필연적으로 **휴먼 에러(실수)**를 유발하며, 개발자가 온전히 개발에만 집중할 수 없게 만듭니다.
이러한 문제를 해결하고 개발 주기를 자동화하여 생산성을 극대화하는 실천 방법론이 바로 **CI/CD(지속적 통합 / 지속적 배포)**입니다. 그리고 이 CI/CD를 가장 쉽고 강력하게 구축할 수 있는 도구 중 하나가 GitHub Actions입니다.
CI/CD란 무엇인가?
CI (Continuous Integration - 지속적 통합)
여러 개발자가 작성한 코드를 중앙 리포지토리(예: GitHub의 main 브랜치)에 정기적으로, 그리고 자주 통합하는 것을 의미합니다. 성공적인 CI의 핵심은 코드가 병합될 때마다 자동화된 빌드와 테스트가 실행되어, 새로운 코드가 기존 시스템을 망가뜨리지 않았는지(Regression) 즉각적으로 검증하는 것입니다.
CD (Continuous Delivery/Deployment - 지속적 제공/배포)
CI를 통과한, 즉 검증이 완료된 코드를 실제 프로덕션 환경(서버)이나 스테이징 환경에 **자동으로 릴리즈(배포)**하는 과정입니다. 사용자는 개발자가 푸시한 최신 기능을 별도의 긴 대기 시간 없이 거의 실시간으로 만나볼 수 있게 됩니다.
왜 GitHub Actions 인가?
과거에는 CI/CD를 구축하기 위해 Jenkins, Travis CI, CircleCI 등 별도의 외부 서비스를 연동하고 복잡한 서버 설정을 거쳐야 했습니다. 하지만 GitHub Actions의 등장으로 생태계가 크게 변했습니다.
- 완벽한 통합: 코드가 저장된 GitHub 리포지토리 내에서 바로 동작하므로 별도의 서비스 가입이나 연동 과정이 필요 없습니다.
- 이벤트 기반 구동:
push,pull request오픈, 특정 브랜치 병합, 주기적 실행(Cron) 등 GitHub 내의 거의 모든 이벤트 트리거에 맞춰 워크플로우 실행할 수 있습니다. - 방대한 오픈소스 액션: 내가 직접 스크립트를 짜지 않아도, AWS 접속, Docker 빌드, 슬랙 알림 등 수많은 동작들이 GitHub Marketplace에 '액션' 단위로 만들어져 있어 블록 조립하듯 가져다 쓰기만 하면 됩니다.
- 넉넉한 무료 할당량: 퍼블릭 리포지토리에서는 무제한 무료이며, 프라이빗 리포지토리도 매월 넉넉한 분량(2,000분)의 실행 시간을 무료로 제공합니다.
GitHub Actions 핵심 개념 잡기
설정 파일을 작성하기 전 알아야 할 4가지 주요 구성 요소입니다.
- Workflow (워크플로우): 전체 자동화 프로세스를 의미합니다.
.github/workflows/디렉토리에 YAML 파일(.yml) 형태로 작성됩니다. - Event (이벤트): 워크플로우를 실행시키는 방아쇠(Trigger)입니다. (예:
main브랜치에 코드가push될 때) - Job (작업): 워크플로우 안에서 실행되는 독립적인 작업 단위입니다. 하나의 워크플로우는 여러 개의 Job을 가질 수 있으며, 기본적으로는 병렬로 실행됩니다. (예:
test-job,deploy-job) - Step (스텝): Job 안에서 순차적으로 실행되는 개별 명령어 단위입니다. 쉘 스크립트를 실행(
run)하거나, 누군가 만들어둔 액션을 가져다 사용(uses)할 수 있습니다.
예제: Node.js 프로젝트 테스트 자동화 (CI) 워크플로우
간단한 React나 Node.js 프로젝트에서 코드가 Push될 때마다 자동으로 npm 패키지를 설치하고 테스트 코드를 실행하는 ci.yml 예제입니다.
# .github/workflows/ci.yml
name: Node.js CI
# 언제 실행될 것인가? (Event)
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build-and-test:
# 어떤 환경(OS)에서 실행할 것인가?
runs-on: ubuntu-latest
steps:
# 1. 현재 리포지토리의 코드를 가상 환경으로 가져옵니다. (Checkout)
- name: Checkout repository
uses: actions/checkout@v3
# 2. Node.js 환경을 세팅합니다.
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm' # npm 캐싱을 통해 다음 빌드 속도를 단축합니다.
# 3. 의존성 패키지 설치
- name: Install dependencies
run: npm ci
# 4. 린트(Lint) 검사 및 테스트 실행
- name: Run lint and tests
run: |
npm run lint
npm run test
마무리
위의 YAML 코드를 프로젝트 최상위 폴더의 .github/workflows/ 안에 저장하고 커밋하여 Push해 보세요. GitHub 리포지토리의 'Actions' 탭으로 이동하면 워크플로우가 빙글빙글 돌며 우분투 가상 환경에서 당신의 코드를 열심히 테스트하고 있는 마법 같은 광경을 볼 수 있습니다.
CI가 완벽하게 구축되었다면, 다음 단계는 이 코드를 AWS EC2나 Vercel과 같은 서버로 전송하는 배포(CD) 파이프라인을 추가하는 것입니다. GitHub Actions를 통해 지루하고 반복적인 수작업에서 벗어나, 창조적인 코드 작성에 더 많은 시간을 투자해 보시기 바랍니다!









