[Git Actions] 모노레포에서 생긴 일

windowook·2025년 8월 14일
post-thumbnail

사건의 배경

완성된 모노레포 프로젝트를 Git Actions로 CI/CD 인프라를 구축하고 있었습니다.
아래는 현재 프로젝트의 디렉토리 구조입니다.

ROOT
├─ .github
│  └─ workflows
│     ├─ preview.yml
│     └─ production.yml
├─ .gitignore
├─ README.md
├─ backend
│  └─ ...
└─ frontend
   └─... 

백엔드와 프론트엔드로 나뉘어져있습니다. 백엔드는 웹소켓으로 업비트의 실시간 데이터만 발사해주는 서버라 테스트 코드도 없고 Railway에 배포되어있는 상태라 Git Actions로 CI 인프라는 구축하지 않고 Railway의 빌드와 배포를 그대로 사용합니다. 저한텐 프론트엔드가 메인입니다.

프론트엔드는 develop 브랜치를 Vercel의 Preview, main 브랜치를 Production으로 배포하는 중이었고 이제 빌드는 Vercel CLI로, 배포만 Vercel에서 하는 것으로 워크플로우를 구성했습니다. 아래는 최종 작성된 yml입니다.

name: Preview 배포 (Develop)

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

on:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop

jobs:
  Deploy-Preview:
    runs-on: ubuntu-latest

    steps:
      - name: 저장소 체크아웃
        uses: actions/checkout@v4

      - name: Node.js 환경 설정
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: pnpm 설치
        uses: pnpm/action-setup@v4
        with:
          version: 10.14.0

      - name: pnpm 캐시 설정
        uses: actions/cache@v4
        with:
          path: ~/.pnpm-store
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('frontend/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: 의존성 설치
        working-directory: ./frontend
        run: pnpm install --frozen-lockfile

      - name: 타입 체크
        working-directory: ./frontend  
        run: npx tsc --noEmit
        continue-on-error: true

      - name: 린트 검사
        working-directory: ./frontend
        run: pnpm run lint
        continue-on-error: true

      - name: Vercel CLI 설치
        run: pnpm install --global vercel@latest

      - name: Vercel 환경 정보 가져오기 (Preview)
        run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

      - name: 프로젝트 빌드
        run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

      - name: Vercel Preview 배포
        id: deploy
        run: |
          url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
          echo "PREVIEW_URL=$url" >> $GITHUB_OUTPUT
          echo "🚀 Preview 배포 완료: $url"

      - name: PR 코멘트
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const { PREVIEW_URL } = process.env;
            const comment = `
            ## 🚀 Preview 배포 완료!

            **Preview URL:** ${PREVIEW_URL}
            **브랜치:** \`${{ github.ref_name }}\`
            **커밋:** \`${{ github.sha }}\`

            배포된 사이트에서 변경사항을 확인해보세요! ✨
            `;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            })
        env:
          PREVIEW_URL: ${{ steps.deploy.outputs.PREVIEW_URL }}

      - name: 배포 성공 알림
        if: success()
        run: |
          echo "✅ Preview 환경에 성공적으로 배포되었습니다!"

문제는 기존에 Git Actions를 사용한 프로젝트는 멀티레포여서 이번 프로젝트에서 겪은 문제의 원인을 만난 적이 없기에, 제가 아주 멍청한 실수를 하여 시간을 꽤나 낭비해버렸습니다...

실수

Error: spawn sh ENOENT가 뭔데?

문제의 에러 로그입니다. 로그에 나와있는 것만 보고는 pnpm 버전이 문제인가 생각했습니다.
그래서 계속 pnpm-lock.yaml의 버전과 package.json의 packageManager 버전을 9.0.0으로 통일하고, yml에도 pnpm 설치 스텝에서 version: 9.0.0을 명시하고 커밋 n 푸쉬를 했지만 해결이 안 됐습니다.

'그럼 Error: spawn sh ENOENT 이게 문제의 원인인가?' 생각하여 shell: bash를 워크 스텝마다 추가하여 해결을 시도했는데 push하는 족족 실패했습니다. 심지어 Claude Code 또한 비슷한 접근법으로 문제를 계속 해결하라고 수정해줘서 비슷한 방법을 조금씩 변형해가며 계속 시도했고, 문제를 해결할 수 없었습니다. Stack Overflow와 Github Issues에 서양 형님들이 비슷한 문제로 올려뒀던 글에도 해답이 딱히 없었고, 저와 동일한 상황은 아니었습니다. 설상가상으로 Vercel 공식문서에서는 pnpm v9는 v10으로 자동 업그레이드하여 인식하니 문제가 없다고 나와있었습니다.

https://vercel.com/changelog/automatic-pnpm-v10-support

아니 그럼 뭐가 문제인건데?

문제라고 하기에도 어이없는...

시간을 계산하면 정확히 어제 밤(8.13 20:00)부터 아무런 진전없이 오늘 낮(8.14 14:00)까지 헤맸습니다. 물론 그 사이에 다른 코드 수정도 좀 하고 잠도 자고 운동도 갔다오고 밥도 먹고 여러가지 했습니다.

어쨌거나 빌드 에러 해결을 위해 push를 자꾸 해버려 커밋 로그와 액션 로그가 더러워질 즈음.. 갑자기 이런 생각이 들더군요.

모노레포인데 설마 계속 ./를 경로로 잡아서 이러는 건 아니겠지?

그래서 frontend 디렉토리의 .vercel/project.json 에 루트 경로 지정을 할 수 있는지 Claude Code에게 물었고, 가능하다며 루트 경로를 세팅해줬습니다.

{
  "projectId": "프로젝트 ID",
  "orgId": "Organization ID",
  "settings": {
    "rootDirectory": "frontend"
  }
}

'되면 다행이고 아님 포기하자'하며 저장하고 깃허브로 push를 했는데..
빌드에 성공했습니다.

그렇습니다 원인은 프론트엔드 디렉토리 경로가 모노레포의 루트로 설정되어있던 것이었습니다..
이딴 거에 이렇게 시간을 허비하니 약간 머리가 멍해지네요 dk w..

마무리

Git Actions는 아주 좋은 도구이지만, 저번 프로젝트에서 구축할 때도 그렇고
뭔가 조금의 잘못된 이슈가 있으면 에러 로그로는 직접적인 원인을 찾기 힘든 거 같습니다.

저번에는 처음에 팀 Organization 리포지토리로 생성했어서 Git Actions와 Vercel로 CI/CD를 구축하려면 개인 리포지토리에 구축할 때와는 아예 yml의 내용이 다르게 작성되어야 하는 것도 처음 알아서 방법을 찾느라 시간 낭비를 꽤 했었습니다. 이번에도 의미없는 시간을 낭비하게 되었네요.. 설정에 문제가 없는데 계속 에러가 터진다면, 보통은 오타나 경로 설정이 원인인거 같습니다.

여러분도 혹시나 시간을 허비하지 않으시려면 등잔 밑을 잘 살펴봅시다😂

profile
안녕하세요

0개의 댓글