0259

FE

[React] React 프로젝트에 Vercel + GitHub Actions로 CI/CD 구축하기

시작하며

지난 번에는 CI/CD에 대한 개념을 배웠다면, 이번에는 Vercel과 GitHub Actions를 활용해 CI/CD를 구축한 전체 과정을 기록해보려고 한다.

Github Actions를 활용한 CI/CD 파이프라인 구축에 대해 이론적으로 접한 적은 많지만, 실제로 이를 해본 적이 없기에, 이번 기록은 다양한 의미를 가진다고 생각한다.

목표 요약

  • 로컬에서 만든 React 프로젝트가

  • GitHub에 Push하여 PR 하면 → 자동으로 빌드 확인(CI)되고

  • Merge 후 Vercel에 배포(CD)되는 구조 만들기!

1단계: React 프로젝트 만들기

아래의 CRA 명령어를 사용하여 새로운 React 프로젝트를 생성한다.

bash
npx create-react-app@latest test-cicd
cd test-cicd

? 이제 test-cicd 폴더 안에 React 앱이 만들어졌다!

2단계: GitHub 저장소 생성 및 연결

1) GitHub에서 새 저장소(repo)를 만들어야 한다.

2) 터미널에서 기존 프로젝트를 연결한다.

? 이제 Github의 해당 Repo에 React 프로젝트가 올라가게 되었다!

3단계: Vercel 연결 및 자동 배포 설정

아래의 과정을 거쳐서 Vercel의 새로운 프로젝트를 생성해보자.

  1. https://vercel.com 접속

  2. GitHub 계정으로 로그인

  3. Add New Project 클릭 → GitHub 레포를 선택

  4. 프레임워크는 자동으로 React로 인식됨

  5. 그대로 Deploy 클릭

Vercel에서 Add -> Proect -> Github Repo 선택 후 보여지는 화면

약 1~2분이 지나면, 아래와 같이, 자동 배포 완료되고 도메인도 만들어진다.

Depoly를 누른 뒤에 배포 성공 후 보여지는 화면

4단계: GitHub Actions로 CI 구축하기

1) 프로젝트 루트에 다음 경로 만들기

(예시 : ./test-cicd/.github/workflows)

code
mkdir -p .github/workflows

2) 그 안에 ci.yml 파일 생성 후 아래 내용 추가하기.

(1) ci.yml 파일 생성 방법

bash
cd workflows
vim ci.yml

(2) ci.yml에 내용 작성 후 저장

YAML
# .github/workflows/ci.yml
name: React CI

on:
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run lint --if-present
      - run: npm test --if-present
      - run: npm run build
  • 작동 원리:

    • main 브랜치에 PR이 올라오면

    • 자동으로 빌드, 테스트, 린트 돌려서 에러 있는지 확인

(3) 수정 사항을 새로 commit하여 main 브랜치로 push하기

code
git add .
git commit -m "add CI workflow"
git push origin main

5단계: 테스트해보기

1) 새로운 브랜치 생성

bash
git checkout -b test-ci

2) 텍스트 수정 (App.js)

JavaScript
// src/App.js
function App() {
  return (
    <div className="App">
      <h1>Hello, CI/CD!</h1> {/* 여기를 수정함 */}
    </div>
  );
}

export default App;
bash
git add .
git commit -m "? CI 테스트를 위한 텍스트 수정"
git push origin test-ci

3) GitHub에서 Pull Request 생성 & CI 결과 확인

(1) GitHub 저장소 접속

test-ci 브랜치로 보낸 PR 확인

(2) test-ci 브랜치에서 → main 브랜치로 PR 생성

: GitHub 저장소에 접속하여 test-ci 브랜치 → main 브랜치로 PR을 생성하면, 자동으로 GitHub Actions가 실행된다/

(3) PR 페이지에서 Checks 탭 클릭하여 실행 중인 Job 확인

  • CI 작업 중이면 Running 또는 In progress 표시

  • 성공하면 ✅ Success, 실패 시 ❌

(4) 예시 : 실패 원인 분석

PR 페이지에서 Checks 탭을 클릭하여 진행 상황을 확인해본 결과 하나의 failing check를 발견하게 되었고, 더 세부적인 내용을 확인했다.

분석해본 결과, 아래 코드와 같은 기존의 테스트 파일 (src/App.test.js)에서 테스트가 실패하여 failing check가 발생한 것이었다.

이는 기본 CRA 템플릿에서 제공한 src/App.test.js "learn react"라는 텍스트를 찾도록 되어 있었기 때문이다. 하지만 우리는 App 컴포넌트에서 "Hello, CI/CD!"로 바꾸었기 때문에 테스트가 실패한 것이다.

bash
test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i); // 부분!
  expect(linkElement).toBeInTheDocument();
});

기존의 테스트 파일(src/App.test.js)의 내용을 아래의 코드로 수정해준 뒤에 다시 test-ci 브랜치로 push를 진행했다.

bash
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders CI/CD text', () => {
  render(<App />);
  const element = screen.getByText(/CI\/CD/i); // 정규표현식도 수정
  expect(element).toBeInTheDocument();
});

다시 PR 페이지에서 Checks 탭을 클릭하여 진행 상황을 확인해본 결과 성공적으로 pass된 것을 확인할 수 있었다.

(5) Merge

성공적으로 Merge를 진행할 수 있었다.

6단계: 모든 변경사항 자동 배포되도록 확인

왼쪽은 수정 전, 오른쪽은 수정 후

CI를 통과한 PR은 main 브랜치로 safely merge 가능하고, merge 즉시 Vercel에서 자동 배포가 진행된다.

이후 확장 아이디어 (프리뷰)

  • ? PR 실패 시 merge 차단
    → GitHub의 브랜치 보호 기능으로, 테스트 실패 시 병합 불가하게 설정 가능

  • ? Slack/Discord 배포 알림
    → 배포 성공/실패 여부를 팀 채널에 자동 전송하여 빠르게 공유

  • ? 스테이징 / 프로덕션 분리
    → develop 브랜치는 스테이징, main은 실제 배포로 분리 운영 가능

  • ? Cypress E2E 테스트 연동
    → UI 동작까지 자동 테스트하여 릴리즈 전 품질을 보장

마무리

처음엔 어렵게 느껴졌지만, 실제로 GitHub Actions와 Vercel을 활용해 CI/CD 흐름을 구성해보니 예상보다 단순했고, 하나씩 차근차근 따라가면 충분히 구현할 수 있었다.

하지만 단순한 빌드, 테스트, 배포만으로는 CI/CD를 안다고 말하긴 어렵다.

이번 경험을 시작점으로 삼아, 테스트 자동화, 환경 분리, 배포 전략 등 더 넓은 CI/CD의 영역을 깊이 있게 공부해야겠다는 생각이 들었다.

기초적인 흐름을 직접 구축해보며, ‘CI/CD는 멀리 있는 개념이 아니라, 직접 만들 수 있는 개발 도구다'라는 확신을 얻게 된 시간이었다.