devops2025-03-18·9 min·146/348

Vercel 배포 자동화 (GitHub Actions)

GitHub Actions를 사용하여 Vercel 배포를 자동화하는 방법을 알아봅니다.

Vercel 배포 자동화 (GitHub Actions)

Introduction

GitHub Actions를 사용하면 Vercel 배포를 자동화하고, 테스트, 빌드, 배포 프로세스를 통합할 수 있습니다. 이 글에서는 GitHub Actions를 사용하여 Vercel 배포를 자동화하는 방법을 알아보겠습니다.

Environment

  • Vercel 프로젝트 (Next.js 14+)
  • GitHub Actions
  • Node.js 18+
  • npm/yarn

Problem

수동 배포 시 발생하는 문제:

# 수동 배포 과정
git push origin main
vercel --prod

# 실수로 잘못된 브랜치를 배포하거나
# 테스트 없이 배포하는 경우 발생

Analysis

GitHub Actions의 장점:

  1. 자동화: 푸시 시 자동으로 배포
  2. 통합: 테스트, 빌드, 배포를 하나의 파이프라인에서 처리
  3. 버전 관리: 배포 이력을 GitHub에서 관리
  4. 협업: 팀원들이 배포 과정을 투명하게 확인

Solution

1. 기본 Vercel 배포 워크플로우

# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run tests
        run: npm test
        
      - name: Install Vercel CLI
        run: npm install --global vercel
        
      - name: Pull Vercel Environment
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
        
      - name: Build
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
        
      - name: Deploy
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

2. 프리뷰 배포 설정

# .github/workflows/preview.yml
name: Preview Deployment
on:
  pull_request:
    branches: [main]

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Vercel CLI
        run: npm install --global vercel
        
      - name: Pull Vercel Environment
        run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
        
      - name: Build
        run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
        
      - name: Deploy
        id: deploy
        run: |
          DEPLOYMENT_URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
          echo "url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
          
      - name: Comment PR
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `Preview deployed: ${{ steps.deploy.outputs.url }}`
            })

3. 환경 변수 관리

# .github/workflows/deploy-with-env.yml
name: Deploy with Environment
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'
          working-directory: ./

4. 테스트 통합

# .github/workflows/test-and-deploy.yml
name: Test and Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run lint
        run: npm run lint
        
      - name: Run tests
        run: npm test
        
      - name: Run build
        run: npm run build

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

5. 슬랙 알림 설정

# .github/workflows/deploy-with-notification.yml
name: Deploy with Notification
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Deploy to Vercel
        id: deploy
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'
          
      - name: Notify Slack
        if: always()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
          text: |
            Deployment ${{ job.status }}
            URL: ${{ steps.deploy.outputs.url }}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

6. 롤백 자동화

# .github/workflows/rollback.yml
name: Rollback Deployment
on:
  workflow_dispatch:
    inputs:
      deployment_id:
        description: 'Deployment ID to rollback'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Vercel CLI
        run: npm install --global vercel
        
      - name: Rollback
        run: |
          vercel rollback ${{ inputs.deployment_id }} --token=${{ secrets.VERCEL_TOKEN }}

7. 배포 상태 확인

// scripts/check-deployment.js
const { execSync } = require('child_process');

function checkDeployment() {
  try {
    const output = execSync('vercel ls --format json', { encoding: 'utf8' });
    const deployments = JSON.parse(output);
    
    const latestDeployment = deployments[0];
    
    console.log('Latest deployment:');
    console.log(`URL: ${latestDeployment.url}`);
    console.log(`Status: ${latestDeployment.readyState}`);
    console.log(`Created: ${latestDeployment.createdAt}`);
    
    return latestDeployment;
  } catch (error) {
    console.error('Failed to check deployment:', error.message);
    process.exit(1);
  }
}

checkDeployment();

Lessons Learned

  1. 시크릿 관리: Vercel 토큰과 같은 시크릿은 GitHub Secrets에 안전하게 저장해야 합니다.
  2. 테스트 우선: 배포 전에 테스트를 실행하면 문제를 조기에 발견할 수 있습니다.
  3. 프리뷰 배포: PR 프리뷰 배포를 통해 변경사항을 미리 확인할 수 있습니다.
  4. 알림 설정: 배포 상태를 팀원들에게 알리면 협업이 용이합니다.
  5. 롤백 전략: 문제가 발생할 경우 빠르게 롤백할 수 있는 전략이 필요합니다.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.