GitHub Actions npm ci 에러: Bun 프로젝트인데 Node로 설정해서 발생한 문제

soleil_lucy·2025년 6월 19일
1

이번 글에서는 GitHub Actions와 Vercel을 사용하여 CI/CD 자동 배포를 설정했으나, CI 과정에서 실패했다는 오류를 해결하는 과정에 대해 작성했습니다.

에러와 관련된 개념 정리

에러를 해결하기 전에, CI/CD가 무엇이며 이를 왜 프로젝트(Receito, 모임 정산 서비스)에 도입하게 되었는지 설명하겠습니다.

CI/CD 란?

CI, CD 설명 그림

CI/CD는 지속적 통합(Continuous Integration, CI)과 지속적 전달/배포(Continuous Delivery/Deployment, CD)를 말합니다. 이 방법론은 소프트웨어 개발과 배포를 자동화하여 효율성과 품질을 높입니다.

CI, Continuous Integration

여러 개발자가 작업한 코드를 중앙 저장소에 자주 통합합니다. 코드가 추가될 때마다 자동으로 빌드와 테스트가 실행되어, 변경 사항이 기존 코드에 문제를 일으키지는 않는지 신속히 확인합니다. 이를 통해 버그를 조기에 발견하고, 개발자 간의 충돌 문제를 줄입니다.

CD, Continuous Delivery/Deployment

지속적 전달은 CI 후 테스트를 통과한 코드를 운영 환경에 배포할 준비를 하는 단계입니다. 배포는 수동으로 결정할 수 있습니다.

지속적 배포는 테스트를 통과한 코드를 자동으로 운영 환경에 배포합니다. 개발자가 코드를 올리면 즉시 사용자에게 전달됩니다.

CI/CD의 이점

  • 개발 속도와 배포 주기 단축
  • 인적 오류 감소
  • 빠른 피드백과 문제 해결
  • 고객 만족도 향상

프로젝트에 CI/CD를 설정한 이유

혼자 진행하는 프로젝트였고 테스트 코드는 없었지만, 빌드 과정의 오류를 빠르게 확인하고 싶었습니다.

과거에는 로컬 환경에서만 테스트하면서 모든 기능을 구현한 후 운영 환경에 배포하려고 했습니다. 하지만 이 과정에서 디자인이 깨지거나 예상치 못한 에러가 발생해, 마무리를 급하게 처리해야 하는 상황이 자주 있었습니다.

그래서 이번에는 초기부터 운영 환경에 배포하면서 문제를 조기에 발견하고, 빠르게 수정하기 위해 CI/CD를 도입했습니다.

이를 통해 운영 환경에서도 안정적으로 작동하는 애플리케이션을 만들고자 했습니다.

Receipto 프로젝트에 CI/CD를 설정하기 위해 GitHub Actions와 Vercel을 사용했습니다.

GitHub Actions? GitHub 저장소와 연동하여 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼입니다. 리포지토리에 변경 내용을 푸시할 때마다 테스트를 실행하거나 병합된 pull request를 프로덕션에 배포하는 워크플로를 만들 수 있습니다.

Vercel? 웹사이트나 웹 애플리케이션을 빠르고 쉽게 배포할 수 있도록 도와주는 플랫폼입니다. 코드를 깃허브(GitHub) 등 버전 관리 저장소에 올리면, Vercel이 자동으로 코드를 가져와 빌드하고, 전 세계 어디서든 접속 가능한 URL로 배포해줍니다. CI/CD(지속적 통합/배포) 기능이 내장되어 있어, 코드에 변경이 생길 때마다 자동으로 테스트와 배포가 이루어지기 때문에 초보자도 복잡한 설정 없이 손쉽게 최신 버전을 공개할 수 있습니다.

GitHub Actions에서 에러 발생

특정 브랜치에서 CI를 수행하도록 워크플로 파일을 설정했습니다. 하지만 프로젝트의 요구사항을 구현하며 반복적으로 커밋과 푸시를 하는 동안, CI가 빌드 단계에서 실패했다는 알림이 뒤늦게 온 것을 발견했습니다. CI 설정 후에 방치해 둔 결과였습니다…

메일 스크린샷

로그 분석 및 원인 파악: npm ci 에러

GitHub에서 로그를 다운로드 받아 분석했습니다.

다운로드 방법:

GitHub Repository > Actions > 에러가 표시된 워크플로우 클릭 > 에러가 발생한 Job 클릭 > 설정 아이콘(톱니바퀴 모양) 클릭 > Download log archive 클릭하여 다운로드)

로그를 확인해 보니 다음과 같은 에러가 있었습니다:

2025-06-18T03:41:47.5441363Z ##[group]Run npm ci
2025-06-18T03:41:47.5441734Z [36;1mnpm ci[0m
2025-06-18T03:41:47.5543650Z shell: /usr/bin/bash -e {0}
2025-06-18T03:41:47.5543983Z ##[endgroup]
2025-06-18T03:41:48.0225178Z npm error code EUSAGE
2025-06-18T03:41:48.0225906Z npm error
2025-06-18T03:41:48.0226961Z npm error The `npm ci` command can only install with an existing package-lock.json or
2025-06-18T03:41:48.0228346Z npm error npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or
2025-06-18T03:41:48.0229883Z npm error later to generate a package-lock.json file, then try again.

...

이 에러는 package-lock.json 파일이 없기 때문에 발생했습니다.

생각해보니, 제 리포지토리는 Bun 환경을 사용하고 있어서 package-lock.json 대신 bun.lock 파일만 존재합니다. 그래서 CI 워크플로 파일에 문제가 있을 것이라고 직감했습니다.

워크플로 파일? GitHub Actions에서 자동화된 작업(워크플로우)을 정의하는 설정 파일입니다. 코드가 깃허브에 올라갈 때마다 자동으로 빌드, 테스트, 배포 같은 작업을 순서대로 실행할 수 있습니다.

쉽게 말해, 워크플로 파일에 "어떤 상황에서(예: push), 어떤 작업을(예: 배포) 어떻게 할지"를 적어두면, GitHub가 알아서 그 과정을 자동으로 처리해주는 역할을 합니다

워크플로 파일 검토

GitHub Actions는 프로젝트 루트의 .github/workflows 폴더에 있는 워크플로 파일을 자동으로 감지해 CI/CD를 수행합니다. 저도 CI 과정을 자동화하기 위해 이 폴더 안에 ci.yml이라는 이름의 워크플로 파일을 만들어두었습니다.

해당 파일을 살펴보니, Node.js 환경으로 설정되어 있었습니다. 워크플로 파일을 작성할 때, 내용을 자세히 검토하지 않은 채 일반적인 예제를 그대로 따라 적용한 것이 분명했습니다😥.

name: CI

on:
  push:
    branches: [develop/v0.0.1]
  pull_request:
    branches: [develop/v0.0.1]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # 1. 소스 체크아웃
      - uses: actions/checkout@v3

      # 2. Node.js 설치
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 18

      # 3. 패키지 의존성 설치
      - name: Install dependencies
        run: npm ci

      # 4. 테스트(있다면)
      # - name: Run tests
      #   run: npm test

      # 5. 빌드
      - name: Build
        run: npm run build

해결 방법

문제를 해결할 방법으로 두 가지가 떠올랐습니다:

  1. 워크플로 파일을 Bun 환경에 맞게 수정합니다. 현재 리포지토리는 Bun 환경으로 설정되어 있기 때문입니다.
  2. 프로젝트 전체를 Node 환경으로 변경합니다.

2번 방법은 변경 작업이 크기 때문에, 시간과 노력이 덜 드는 1번 방법으로 진행하기로 결정했습니다.

문제 해결 과정: 워크플로 파일을 Bun 환경으로 수정

Bun 공식 문서를 참고하여 워크플로 파일을 수정했습니다. 이를 통해 프로젝트에 적합한 설정을 적용할 수 있었습니다.

Bun 환경에 맞게 워크플로 수정

name: Receipto Bun CI

on:
  push:
    branches: [develop/v0.0.1]
  pull_request:
    branches: [develop/v0.0.1]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # 1. 소스 체크아웃
      - uses: actions/checkout@v4

      # 2. bun 설치 (공식 curl 스크립트 사용)
      - name: Install bun
        run: |
          curl -fsSL https://bun.sh/install | bash
          echo "$HOME/.bun/bin" >> $GITHUB_PATH

      # 3. bun 환경 확인 (버전 체크)
      - name: Check bun version
        run: bun --version

      # 4. 패키지 의존성 설치 (bun)
      - name: Install dependencies
        run: bun install

      # 5. 코드 품질 체크
      - name: Run linter
        run: bun run lint

      - name: Check code formatting
        run: bun run format:check

      # 6. 빌드
      - name: Build
        run: bun run build

워크플로 파일 설명

위에 제가 작성한 워크플로 파일에 대해 설명하겠습니다. 저는 테스트 코드를 작성하지 않았기에 테스트 단계는 작성하지 않았습니다.

워크플로우 기본 정보

name: Receipto Bun CI
  • name: 워크플로의 이름을 지정합니다. 여기서는 Receipto Bun CI라고 지었습니다.

트리거 조건(언제 실행되는가?)

on:
  push:
    branches: [develop/v0.0.1]
  pull_request:
    branches: [develop/v0.0.1]
  • on: 워크플로를 트리거하는 이벤트를 정의합니다.
  • pushpull_request 는 설정해 놓은 브랜치에 푸시나 풀 리퀘스트가 있을 때 워크플로가 실행되도록 핳ㅂ니다.
  • 해당 워크플로는 현재 개발을 진행 중인 develop/v0.0.1 브랜치만 트리거 되도록 설정했습니다.

작업(Job) 환경 설정

jobs:
  build:
    runs-on: ubuntu-latest
  • jobs: 워크플로 내에서 실행될 작업을 정의합니다.
  • build: 실행할 작업의 이름입니다.
  • runs-on: 작업이 실행될 환경을 지정합니다. 여기서는 ubuntu-latest를 사용합니다.

실행 단계별 상세 분석

Step1: 소스 코드체크 아웃

steps:
  - uses: actions/checkout@v4

Step2: Bun 런타임 설치

- name: Install bun
  run: |
    curl -fsSL https://bun.sh/install | bash
    echo "$HOME/.bun/bin" >> $GITHUB_PATH

Bun 공식 문서에 나와있는걸 참고해서 작성했습니다.

Step3: Bun 환경 확인

- name: Check bun version
  run: bun --version

Bun이 제대로 설치되었는지 확인합니다.

Step4: 의존성 설치

- name: Install dependencies
  run: bun install

Step5: 린팅/포맷팅 체크

- name: Run linter
  run: bun run lint

- name: Check code formatting
  run: bun run format:check

Step6: 프로젝트 빌드

- name: Build
  run: bun run build

이러한 설정을 통해 자동으로 코드 변경이 반영되고, 필요한 의존성을 설치하고, 빌드가 이루어집니다.

결과 확인

수정한 워크플로 파일을 푸시하여 결과를 확인해 보겠습니다.

GitHub Repository Actions 탭에서 빌드 결과 확인

이미지에서 보시다시피, 에러 없이 통합과 빌드가 성공적으로 완료되었습니다.

회고

처음에는 깊이 생각하지 않고 CI 설정 파일을 작성해 에러가 발생했습니다. 이 경험을 통해, CI를 설정할 때 현재 사용 중인 런타임 환경과 패키지 매니저를 고려해야 한다는 점을 배웠습니다.

그동안 CI/CD라는 용어를 자주 들어왔지만, 명확하게 설명하지 못했는데 이번 기회를 통해 그 개념과 사용 이유를 제대로 이해할 수 있었습니다.

사실 GitHub Actions와 Vercel을 사용한다고 했지만, 현재 워크플로 파일에는 Vercel 배포 내용이 포함되어 있지 않습니다. 그래서 GitHub Actions가 빌드를 수행하고, Vercel은 자체적으로 다시 빌드하여 에러를 확인한 후 배포하는 식으로 진행됩니다. 이 과정을 통해, 다음에는 Vercel CLI를 사용하여 중복 빌드를 피하고 효율적인 배포 과정을 갖춰보고 싶습니다.

일단 이 글은 CI 에러를 해결해서 기쁜 상태로 마무리를 하도록 하겠습니다.

참고 자료

profile
여행과 책을 좋아하는 개발자입니다.

0개의 댓글