Skip to content

Turborepo 모노레포에서 CI를 활용한 자동 코드 품질 유지

Choi Jeongmin edited this page Dec 1, 2024 · 1 revision

📄 Turborepo 모노레포에서 CI를 활용한 자동 코드 품질 유지

‘Ask-It’ 팀은 turborepo 기반의 모노레포에서 PR이 올라올 때마다 Linter와 Formatter를 자동으로 실행하는 CI 파이프라인을 추가했습니다. 이를 통해 클라이언트와 서버 애플리케이션 모두에서 코드 품질을 자동으로 유지하고, 일관된 코딩 표준을 보장하여 코드 리뷰를 간소화하고 팀 생산성을 향상시킵니다.

🧩 배경 및 필요성

코드베이스가 확장되다 보면 일관된 코드 스타일과 품질을 유지하는 것이 어려울 것이라고 판단되었습니다. 모노레포를 구축하기 위해 turborepo 를 사용하였고, 그 안에서는 클라이언트와 서버를 포함한 애플리케이션 레이어가 있습니다. 수동으로 Linter와 Formatter를 실행하는 것은 시간이 소요되고 번거로운 일입니다. 이러한 비효율성을 해소하고 코드 품질을 자동으로 유지하기 위해 CI 파이프라인에 Linter와 Formatter를 통합하기로 결정했습니다.

🗺️ 문제 해결 과정

모노레포 구조

‘Ask-It’ 팀의 모노레포 구조는 아래와 같습니다.

ask-it/
├── apps/
│   ├── client/
│   └── server/
├── package.json
├── turbo.json

Linter와 Formatter 구성

각 패키지의 package.json 파일에 해당 명령어를 설정합니다.

{
  "name": "client",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite --host",
    "build": "tsc -b && vite build",
    "lint": "eslint . --fix",
    "format": "prettier --write .",
    "preview": "vite preview"
  },
  // 생략
}
{
  "name": "server",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    // 생략
  },
  // 생략
}

Github Actions 워크플로우 설정

name: Lint & Format

on:
  pull_request:
    branches: ['main']

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: ${{ github.head_ref }}
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install pnpm
        run: npm install -g pnpm

      - name: Install dependencies
        run: pnpm install

      - name: Install Turborepo
        run: npm install turbo -g

      - name: Run ESLint
        run: turbo run lint

      - name: Run Prettier
        run: turbo run format

      - name: Commit changes if any
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git config --global user.name 'github-actions[bot]'
          git config --global user.email 'github-actions[bot]@users.noreply.github.com'
          branch_name="${{ github.head_ref }}"
          git diff --quiet || { git add . && git commit -m 'chore: auto-fix linting and formatting issues' && git push origin "$branch_name"; }

이 워크플로우는 main 브랜치로의 PR이 생성될 때마다 트리거되어, Linter와 Formatter를 실행하고 자동으로 수정 사항을 커밋합니다.

  • 여기에서는, turborepo 를 전역적으로 설치하여서 해당 명령어로 실행하고 있지만, 지역적으로 설치된 turborepo 를 이용할 수 있습니다. 루트의 package.json 파일에 명령어를 설정하고 실행하거나, pnpm dlx 와 같은 도구를 이용합니다.

Turborepo의 turbo.json 설정

turbo.json 파일에서 Linter와 Formatter 작업을 정의합니다.

{
  "tasks": {
    "lint": {
      "dependsOn": [],
      "outputs": []
    },
    "format": {
      "dependsOn": [],
      "outputs": []
    }
  }
}

이를 통해 turborepo 가 Linter와 Formatter 작업을 모든 패키지에서 효율적으로 실행하도록 구성했습니다.

📈 결과 및 성과

  • 자동화된 코드 품질 유지
    • PR 시마다 Linter와 Formatter가 자동으로 실행되어 코드 품질을 유지할 수 있었습니다.
  • 코드 리뷰 효율성 향상
    • 스타일 이슈가 미리 해결되어 리뷰어는 로직에 집중할 수 있습니다.
  • 일관된 코드 스타일
    • 모든 팀원이 동일한 코드 스타일을 따르게 되어 협업이 수월해졌습니다.
  • 개발 생산성 향상
    • 자동화로 인해 수동 작업이 줄어들어 개발 속도가 빨라졌습니다.

현재는 프로젝트에 테스트가 포함되어있지 않아, 테스트를 실행하지는 않지만 각 애플리케이션에서 테스트를 추가하고 CI 파이프라인에 추가하여 안정성을 높일 수 있으면 좋을 것 같습니다.

Clone this wiki locally