2026. 7. 2.

로컬은 통과하는데 Actions만 실패할 때, Node 18/20 차이로 CI 살리기

로컬에서는 npm test가 통과하는데 GitHub Actions에서만 실패하면 코드 전체보다 Node 버전, package.json engines, setup-node 값을 먼저 맞춰야 합니다. 3분 안에 실패 원인을 좁히는 순서입니다.

4 min read
로컬은 통과하는데 Actions만 실패할 때, Node 18/20 차이로 CI 살리기 대표 이미지

AI가 고친 코드가 내 컴퓨터에서는 통과하는데 GitHub Actions에서만 빨간색으로 멈추면, 초보자는 보통 마지막에 바꾼 파일부터 다시 뒤집습니다. 하지만 실패 로그에 node, engine, npm ci, setup-node가 보이면 먼저 코드를 고칠 일이 아닐 수 있습니다. 로컬 Node 버전과 Actions Node 버전이 다른지를 3분 안에 확인해야 합니다.

docs.github.com의 Node.js 빌드 가이드는 workflow에서 actions/setup-node로 Node 버전을 지정하는 예시를 보여 줍니다. github.com의 actions/setup-node 저장소도 node-version 입력값으로 사용할 Node 버전을 정한다고 설명합니다. docs.npmjs.com의 npm ci 문서는 lockfile을 기준으로 깨끗하게 설치하는 명령을 안내합니다. 그래서 CI에서만 실패한다면 "테스트가 틀렸다"보다 CI가 로컬과 같은 환경에서 실행되는지를 먼저 봅니다.

로컬 터미널, workflow node-version, GitHub Actions 로그를 비교하는 3단계 흐름

30초 안에 실패한 단계 이름부터 봅니다

Actions 화면에서 실패한 job을 열고, 빨간색으로 멈춘 step 이름을 봅니다. Set up Node.js, Install dependencies, npm ci, npm test, build 중 어디에서 멈췄는지에 따라 확인할 곳이 달라집니다.

실패한 위치먼저 볼 것의미
Set up Node.js.github/workflows/*.ymlnode-versionCI가 어떤 Node로 실행되는지 정하는 단계입니다
npm cipackage-lock.json, engines, Node 버전의존성 설치 환경이 로컬과 다를 수 있습니다
npm test실패한 테스트 명령과 Node 출력설치는 됐지만 실행 환경 차이가 남아 있을 수 있습니다
npm run build빌드 로그 첫 에러프레임워크나 패키지 요구 버전과 맞지 않을 수 있습니다

여기서 중요한 행동은 로그 전체를 AI에게 던지는 것이 아닙니다. 실패한 step 이름과 첫 에러 10줄만 떼어 봅니다. 첫 에러에 Expected version, Unsupported engine, node, npm, corepack 같은 단어가 있으면 Node 버전 점검으로 들어갑니다.

Set up Node.js
Node.js version: 18.19.0

npm ERR! notsup Unsupported engine
npm ERR! notsup Required: {"node":">=20"}
npm ERR! notsup Actual:   {"node":"18.19.0"}

이 로그라면 React 컴포넌트나 테스트 코드를 고칠 차례가 아닙니다. Actions가 Node 18로 실행되는데 프로젝트나 패키지가 Node 20 이상을 요구하는 상황입니다.

1분째에는 로컬 Node 버전을 숫자로 확인합니다

로컬 터미널에서 성공했다는 느낌만 믿지 말고 버전을 숫자로 찍습니다.

node -v
npm -v
npm test

예를 들어 로컬이 v20.11.0이고 Actions 로그가 18.19.0이면, 같은 코드가 다른 런타임에서 실행된 것입니다. 이때 AI에게 "테스트 고쳐줘"라고 요청하면, 통과하던 테스트까지 바뀔 수 있습니다. 먼저 요청해야 할 것은 workflow의 Node 버전과 package.json 요구 버전 비교입니다.

package.jsonengines가 있다면 같이 봅니다.

{
  "engines": {
    "node": ">=20"
  }
}

engines가 Node 20 이상인데 Actions가 Node 18이면, 실패 원인은 코드가 아니라 CI 설정일 가능성이 큽니다. 반대로 engines가 없고 패키지 에러도 없다면 다음 단계에서 workflow 값을 직접 확인합니다.

2분째에는 setup-node 값을 고정합니다

.github/workflows/ci.yml이나 비슷한 파일을 열고 actions/setup-node 단계가 있는지 봅니다. GitHub 공식 예시는 Node.js 프로젝트에서 checkout 뒤에 setup-node를 두고, 그 다음 install과 test를 실행하는 흐름을 씁니다.

name: CI

on:
  push:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm test

node-version이 비어 있거나 오래된 값이면 로컬과 맞춥니다. 프로젝트가 Node 20으로 개발되고 있다면 node-version: 20처럼 명확히 둡니다. latest처럼 넓은 표현은 편해 보이지만, 초보자가 실패 원인을 좁힐 때는 불리합니다. CI는 예측 가능해야 고칠 수 있습니다.

이미 node-version: 20인데 실패한다면 로그에 실제로 찍힌 Node 버전을 다시 봅니다. workflow 파일이 여러 개이거나, 실패한 job이 다른 workflow를 쓰고 있을 수 있습니다. 파일 하나만 고쳤는데 계속 실패하면 .github/workflows 폴더의 다른 yml도 검색합니다.

Node 버전 3분 점검 체크리스트와 CI pipeline 흐름

3분째에는 실패한 명령만 로컬에서 다시 실행합니다

버전을 맞춘 뒤에는 로컬에서 Actions와 같은 명령만 다시 실행합니다. npm 공식 문서의 npm ci는 기존 node_modules를 전제로 하는 설치가 아니라 lockfile 기준으로 새로 설치하는 흐름입니다. 그래서 CI 재현에는 npm install보다 npm ci가 더 가깝습니다.

rm -rf node_modules
npm ci
npm test

Windows PowerShell에서는 이렇게 실행합니다.

Remove-Item -Recurse -Force node_modules
npm ci
npm test

여기서 로컬도 실패하면 이제 코드나 lockfile 문제로 좁혀집니다. 로컬은 계속 통과하고 Actions만 실패한다면 secrets, OS 차이, 대소문자 파일명, 브라우저 테스트 환경처럼 CI 전용 조건을 봅니다. 하지만 Node 버전 로그가 다르다면 다른 문제로 넘어가기 전에 먼저 그 차이를 없애야 합니다.

AI에게는 아래처럼 범위를 좁혀 묻습니다.

GitHub Actions에서만 실패합니다.
로컬 node -v: v20.11.0
Actions 로그의 Node.js version: 18.19.0
package.json engines: {"node": ">=20"}

.github/workflows/ci.yml에서 Node 버전을 로컬과 맞추는 최소 수정만 제안해 주세요.
테스트 코드나 앱 코드는 바꾸지 말고, workflow 수정 전후 차이를 설명해 주세요.

이 프롬프트의 핵심은 앱 코드 수정을 금지하고 workflow만 보게 하는 것입니다. CI 실패를 만날 때마다 전체 코드를 다시 만들면 통과하던 로컬 상태까지 잃기 쉽습니다.

코드 문제가 아니라 환경 문제인지 가르는 기준

아래 세 칸 중 하나라도 맞으면 먼저 환경 차이를 봅니다.

신호판단다음 행동
로컬 Node와 Actions Node가 다름환경 문제 가능성이 큽니다setup-node 값을 로컬과 맞춥니다
Unsupported engine이 보임패키지 요구 버전과 실행 버전이 다릅니다package.json engines와 로그를 비교합니다
npm ci에서만 실패lockfile이나 설치 환경 문제일 수 있습니다lockfile 변경 여부와 Node 버전을 같이 봅니다
같은 명령이 로컬에서도 실패코드나 테스트 문제 가능성이 커집니다첫 에러 파일부터 고칩니다

초보자에게 가장 손해가 큰 실수는 Actions 로그를 "GitHub가 이상하다" 또는 "내 코드가 전부 틀렸다"로 바로 해석하는 것입니다. 둘 다 아닐 수 있습니다. 로컬 성공과 CI 실패 사이의 차이 하나를 찾는 일이 먼저입니다.

오늘은 Node 버전 한 줄만 맞춥니다

이번 상황의 목표는 CI를 완전히 이해하는 것이 아닙니다. 로컬에서 통과한 코드가 Actions에서만 실패할 때, Node 버전 차이 때문에 실패했는지 3분 안에 가르는 것입니다.

오늘 순서는 네 줄이면 충분합니다.

1. Actions에서 실패한 step 이름을 본다.
2. 로컬에서 node -v와 npm -v를 찍는다.
3. package.json engines와 setup-node node-version을 비교한다.
4. npm ci부터 다시 실행해 같은 실패가 나는지 확인한다.

이 네 줄을 채운 뒤에도 실패하면 그때 테스트 코드, 환경변수, OS 차이로 넘어갑니다. 하지만 Node 버전이 다르다면 먼저 workflow 한 줄을 맞추세요. 코드를 고치기 전 CI 실행 환경을 맞추는 것이 이번 문제의 첫 행동입니다.

참고 출처

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.