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 프로젝트를 생성한다.
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의 새로운 프로젝트를 생성해보자.
GitHub 계정으로 로그인
Add New Project 클릭 → GitHub 레포를 선택
프레임워크는 자동으로 React로 인식됨
그대로 Deploy 클릭

Vercel에서 Add -> Proect -> Github Repo 선택 후 보여지는 화면
약 1~2분이 지나면, 아래와 같이, 자동 배포 완료되고 도메인도 만들어진다.

Depoly를 누른 뒤에 배포 성공 후 보여지는 화면
4단계: GitHub Actions로 CI 구축하기
1) 프로젝트 루트에 다음 경로 만들기
(예시 : ./test-cicd/.github/workflows)
mkdir -p .github/workflows
2) 그 안에 ci.yml 파일 생성 후 아래 내용 추가하기.
(1) ci.yml 파일 생성 방법
cd workflows
vim ci.yml(2) ci.yml에 내용 작성 후 저장
# .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하기
git add .
git commit -m "add CI workflow"
git push origin main
5단계: 테스트해보기
1) 새로운 브랜치 생성
git checkout -b test-ci2) 텍스트 수정 (App.js)
// src/App.js
function App() {
return (
<div className="App">
<h1>Hello, CI/CD!</h1> {/* 여기를 수정함 */}
</div>
);
}
export default App;git add .
git commit -m "? CI 테스트를 위한 텍스트 수정"
git push origin test-ci3) 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!"로 바꾸었기 때문에 테스트가 실패한 것이다.
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i); // 이 부분!
expect(linkElement).toBeInTheDocument();
});기존의 테스트 파일(src/App.test.js)의 내용을 아래의 코드로 수정해준 뒤에 다시 test-ci 브랜치로 push를 진행했다.
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는 멀리 있는 개념이 아니라, 직접 만들 수 있는 개발 도구다'라는 확신을 얻게 된 시간이었다.