Skip to content

프론트엔드 빌드 배포 환경 및 CI 구축

Seongjin Hong edited this page Jul 26, 2024 · 6 revisions

AWS에서 프론트엔드 리소스 빌드 및 배포 환경 구축

개요

  • fe/develop 브랜치에서 fe/main 브랜치로 PR이 병합된 경우 GitHub Action을 통해 FE 리소스 빌드가 자동 수행됩니다.
  • 빌드된 리소스는 자체 생성한 Self-hosted Runner를 거쳐 S3로 자동 업로드되며, 해당 업로드 경로는 CloudFront가 바라보도록 되어 있습니다.
  • 이처럼 코드 변경사항을 빌드, 테스트하고 AWS 기반 환경으로 배포하는 과정을 자동화하는 CD(Continuous Delivery)를 구현한 상태입니다.

배포 정보

FE 리소스 빌드 및 배포 구조

FE CD 구현 다이어그램

CI

개요

크루루의 FE CI는 아래의 두 케이스에 대응하여 실행됩니다.

  1. 기능 브랜치에서 fe/develop 브랜치로 PR 생성 또는 리뷰 요청된 경우
  2. 기능 브랜치에서 fe/develop 브랜치로 PR이 병합된 경우

1번의 경우는 Jest&RTL 테스트까지만 실행되며, 2번의 경우에는 이후 Storybook 빌드 및 배포, 아티팩트 생성까지 실행됩니다. 따라서 본 문서에서는 현재까지 구현된 CI의 전체 구조를 파악할 수 있는 2번 케이스 기준으로 서술합니다.

FE CI 워크플로우 구조

FE CI 워크플로우 구조 다이어그램

1. 풀 리퀘스트 생성

기능 브랜치에서 fe/develop 브랜치로 PR 병합 이벤트가 발생하면, GitHub Actions 워크플로우가 동작하게 됩니다. 이 워크플로우는 GitHub에서 자체 지원하는 Runner Instance에서 동작합니다.

2. 코드베이스에 대한 테스트 실행

Jest와 React Testing Library(RTL)를 사용하여 코드베이스에 대한 단위 및 통합 테스트를 실행합니다.

  • 테스트가 실패하면 워크플로우가 즉시 중단됩니다. 모든 테스트를 통과한 코드만 빌드되도록 보장하기 위함입니다.
  • 현재는 Jest와 RTL만 적용되어 있으나, 추후 필요시 Cypress 등 E2E 테스트 과정도 포함될 수 있습니다.

3. 빌드 및 아티팩트 생성

테스트가 성공적으로 완료되면 FE 애플리케이션을 빌드합니다. 빌드 아티팩트가 fe-dev-dist 이름으로 생성되고 저장됩니다.

4. Storybook 배포

애플리케이션 빌드와 병행하여 Storybook을 사용해 UI 컴포넌트를 독립적으로 문서화하고 테스트합니다.

5. Chromatic에 게시

Storybook 빌드가 완료되면 Chromatic에 배포됩니다. Chromatic은 시각적 테스트와 UI 리뷰를 위한 플랫폼으로, FE/BE 크루들이 모두 신규 배포된 컴포넌트의 UI 변경 사항을 간편하게 검토할 수 있도록 하기 위해 도입했습니다.

FE CI 워크플로우 구현 코드

1. `fe/develop` 브랜치로 PR 생성 또는 리뷰 요청된 경우
name: FE/CI - 테스트 실행 및 검증

on:
  pull_request:
    types: [opened, ready_for_review]
    branches:
      - fe/develop

jobs:
  run-test-pr-opened:
    if: startsWith(github.head_ref, 'fe-')
    runs-on: ubuntu-22.04
    permissions:
      pull-requests: write
    defaults:
      run:
        working-directory: ./frontend

    steps:
      - name: 저장소 checkout
        uses: actions/checkout@v4

      - name: Node.js 셋업
        uses: actions/setup-node@v4
        with:
          node-version: 20.x

      - uses: actions/cache@v4
        id: npm-cache
        with:
          path: |
            frontend/node_modules
            ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      - name: 애플리케이션 의존성 항목들 설치
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: 백엔드 API 연동용 환경변수 설정
        run: |
          echo "REACT_APP_CRURU_API_URL=${{ secrets.API_URL }}" >> .env.production

      - name: 애플리케이션 기능 테스트
        run: npm run test -- --passWithNoTests
2. `fe/develop` 브랜치로 PR이 병합된 경우
name: FE/CI - 기능 테스트, 빌드 및 Chromatic 배포

on:
  push:
    branches:
      - fe/develop

jobs:
  build:
    runs-on: ubuntu-22.04
    defaults:
      run:
        working-directory: ./frontend
    concurrency:
      group: ${{ github.workflow }}
      cancel-in-progress: true

    steps:
      - name: 저장소 checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Node.js 셋업
        uses: actions/setup-node@v4
        with:
          node-version: 20.x

      - uses: actions/cache@v4
        id: npm-cache
        with:
          path: |
            frontend/node_modules
            ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      - name: 애플리케이션 의존성 항목들 설치
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: 백엔드 API 연동용 환경변수 설정
        run: |
          echo "REACT_APP_CRURU_API_URL=${{ secrets.API_URL }}" >> .env.production

      - name: 애플리케이션 기능 테스트
        run: npm run test -- --passWithNoTests

      - name: 애플리케이션 빌드
        run: npm run build

      - name: 컴포넌트 Storybook을 Chromatic으로 배포
        uses: chromaui/action@latest
        with:
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
          workingDir: frontend

      - name: 빌드된 파일을 artifact로 업로드
        uses: actions/upload-artifact@v4
        with:
          name: fe-dev-dist
          path: frontend/dist