Advanced (업데이트: 2026. 6. 2.)

Claude Code로 Changesets 버전 관리를 안전하게 운영하기

Claude Code와 Changesets로 SemVer, 모노레포, CI, CHANGELOG, npm 공개 위험을 관리합니다.

Claude Code로 Changesets 버전 관리를 안전하게 운영하기

Claude Code를 release 작업에 쓰면 속도는 빨라집니다. 하지만 package version은 대충 맡기면 안 됩니다. breaking change를 patch로 내보내면 사용자의 build가 깨지고, internal package를 실수로 npm에 공개하면 되돌리기 어렵습니다. Changesets는 PR 단계에서 “어떤 package를 왜 어떤 버전으로 올리는지” 기록하게 해 주는 도구입니다.

이 글은 Claude Code와 Changesets를 함께 쓰는 실무 흐름을 다룹니다. SemVer 기본, release note, monorepo package, private/internal package, GitHub Actions release flow, npm publish 위험, CHANGELOG 품질, AI가 잘못된 version bump를 만들지 않게 하는 review prompt까지 포함합니다. 기준 문서는 SemVer, Changesets, npm publishing docs, GitHub Actions docs입니다. 함께 보면 좋은 글은 CLAUDE.md 베스트 프랙티스, CI/CD 설정, 모노레포 관리입니다.

SemVer를 먼저 고정한다

SemVer는 semantic versioning, 즉 의미가 있는 버전 번호입니다. 1.4.2major.minor.patch입니다. patch는 공개 계약을 바꾸지 않는 버그 수정, minor는 하위 호환 기능 추가, major는 사용자의 코드 수정이 필요할 수 있는 breaking change입니다.

공개 계약은 함수 이름만 뜻하지 않습니다. React props, CSS token, CLI flag, exit code, default behavior, export된 TypeScript type도 포함됩니다. Claude Code에게 이 기준을 prompt에 넣지 않으면, diff 크기나 commit message만 보고 잘못된 bump를 추천할 수 있습니다.

실무 use case는 다음과 같습니다.

Use case위험Claude Code가 확인할 것
UI component packageprops, variant, CSS token, peer dependency공개 API 변화와 bump가 맞는지
CLI packagecommand, flag, exit codeREADME, test, 구현이 일치하는지
monorepo packageworkspace dependency range의존 package도 release가 필요한지
internal packagenpm 오공개private, ignore, registry, token

초기 설정

Changesets를 설치하고 초기화합니다.

npm install -D @changesets/cli @changesets/changelog-github
npx changeset init

.changeset/config.json은 다음처럼 시작합니다.

{
  "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
  "changelog": [
    "@changesets/changelog-github",
    {
      "repo": "your-org/your-repo"
    }
  ],
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}

fixed는 항상 같은 version을 유지할 package 묶음입니다. linked는 관련 package를 함께 bump하지만 각 version은 유지합니다. updateInternalDependencies는 workspace 내부 의존 range를 어떻게 갱신할지 정합니다. monorepo에서는 로컬 build가 성공해도 publish 후 사용자 환경에서 dependency가 깨질 수 있기 때문에 중요합니다.

package scripts도 명시합니다.

{
  "scripts": {
    "changeset": "changeset",
    "changeset:status": "changeset status --since=origin/main",
    "version": "changeset version",
    "release": "changeset publish",
    "build": "tsc -p tsconfig.json",
    "test": "vitest run"
  }
}

changeset 작성

공개 package에 영향을 주는 PR에서는 다음을 실행합니다.

npx changeset

예시입니다.

---
"@myapp/ui": minor
"@myapp/utils": patch
---

Add the `outline` variant to Button and keep the existing `solid` and `ghost` variants compatible.

Fix `formatCurrency` so it handles zero-decimal currencies without rounding errors.

@myapp/ui는 하위 호환 기능 추가라서 minor, @myapp/utils는 기존 함수의 버그 수정이라서 patch입니다. props 제거, CLI flag 이름 변경, default behavior 변경은 major 후보로 검토해야 합니다.

Claude Code에는 이렇게 요청합니다.

현재 PR diff를 읽고 Changesets changeset 초안을 작성해 주세요.

규칙:
- SemVer를 따른다: breaking change는 major, 하위 호환 기능은 minor, 수정은 patch
- package.json version을 직접 수정하지 않는다
- npm publish를 실행하지 않는다
- private: true package를 publish 계획에 넣지 않는다

출력:
- 변경된 package 목록
- package별 추천 bump
- 추천 이유
- .changeset/*.md 본문 초안
- 사람이 판단해야 할 불확실한 점

monorepo와 internal package

실제 repository에는 publish 대상 package와 배포용 app이 함께 있습니다. 예를 들어 @myapp/ui는 npm에 공개하고, @myapp/app은 웹앱으로만 deploy합니다. publish하지 않을 package는 명확히 표시합니다.

{
  "name": "@myapp/app",
  "private": true,
  "version": "0.0.0",
  "scripts": {
    "build": "next build"
  },
  "dependencies": {
    "@myapp/ui": "workspace:*"
  }
}

Changesets config에서도 제외 대상을 관리합니다.

{
  "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
  "changelog": [
    "@changesets/changelog-github",
    {
      "repo": "your-org/your-repo"
    }
  ],
  "commit": false,
  "fixed": [
    ["@myapp/core", "@myapp/cli"]
  ],
  "linked": [
    ["@myapp/ui", "@myapp/theme"]
  ],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": ["@myapp/app", "@myapp/docs"]
}

사내 registry에 publish하는 package는 registry를 명시하고 public npm token과 분리합니다.

{
  "name": "@my-company/internal-kit",
  "version": "1.8.0",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com",
    "access": "restricted"
  }
}

GitHub Actions release flow

공식 changesets/action을 쓰면 version PR 생성과 merge 후 publish를 자동화할 수 있습니다.

name: Release

on:
  push:
    branches:
      - main

concurrency: release-${{ github.ref }}

permissions:
  contents: write
  pull-requests: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: "https://registry.npmjs.org"

      - run: npm ci
      - run: npm test
      - run: npm run build

      - name: Create release PR or publish to npm
        uses: changesets/action@v1
        with:
          version: npm run version
          publish: npm run release
          title: "chore: version packages"
          commit: "chore: version packages"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

PR에는 changeset check를 둡니다.

name: Changeset Check

on:
  pull_request:
    branches:
      - main

permissions:
  contents: read

jobs:
  changeset:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx changeset status --since=origin/main

문서 전용 PR은 changeset이 필요 없을 수 있습니다. skip label을 쓴다면 workflow에 명확히 적고, Claude Code가 임의로 넓은 예외를 추가하지 않게 해야 합니다.

CHANGELOG 품질

나쁜 release note는 사용자에게 도움이 되지 않습니다.

---
"@myapp/ui": minor
---

Update Button.

좋은 release note는 무엇이 바뀌었고 사용자가 무엇을 해야 하는지 설명합니다.

---
"@myapp/ui": minor
---

Add `variant="outline"` to `Button`.

Existing `solid` and `ghost` variants keep the same props and class names. Teams using a custom theme should add `--button-outline-border` only if they want to override the default border color.

Claude Code review prompt입니다.

이 changeset을 공개 CHANGELOG 문구로 검토해 주세요.

확인:
- 사용자가 영향 범위를 이해할 수 있는가
- major/minor/patch 판단과 문구가 일치하는가
- migration이 필요하면 절차가 있는가
- "개선", "업데이트" 같은 모호한 표현만 있는가
- package, 함수, props 이름이 실제로 존재하는가

의심스러운 점은 수정하지 말고 질문으로 나열해 주세요.

실패 모드

첫째, “version 올려 줘”라고만 요청하는 것입니다. Claude Code가 package.json을 직접 수정하고 changeset을 남기지 않을 수 있습니다.

둘째, breaking change를 minor로 내는 것입니다. TypeScript type 변경도 소비자의 build를 깨면 major 후보입니다.

셋째, internal package 오공개입니다. private: true, ignore, publishConfig.registry, CI token scope, npm pack --dry-run을 함께 확인합니다.

넷째, internal dependency bump 누락입니다. @myapp/core가 바뀌었는데 @myapp/cli dependency range가 그대로면 사용자 환경에서 불일치가 생깁니다.

로컬 검증

release 전에 실행합니다.

npm run changeset:status
npm test
npm run build
npm run version -- --snapshot canary
git diff -- package.json package-lock.json pnpm-lock.yaml yarn.lock CHANGELOG.md
npm pack --dry-run

snapshot은 실제 publish 없이 version 계산과 CHANGELOG를 확인하는 용도입니다. npm pack --dry-run은 tarball에 들어갈 파일을 보여 주므로 .env, 내부 문서, 큰 fixture, 누락된 dist를 찾는 데 좋습니다.

수익화와 팀 도입

안정적인 release flow는 수익과 연결됩니다. UI kit, CLI, SDK, template package가 신뢰성 있게 공개되면 유료 템플릿, 팀 교육, 내부 플랫폼 구축, 컨설팅으로 이어질 수 있습니다. 반대로 잘못된 version bump와 모호한 CHANGELOG는 신뢰를 바로 깎습니다.

실제 repository에 적용하려면 Claude Code 교육과 상담에서 Changesets 설정, CLAUDE.md 규칙, GitHub Actions, npm token 경계, release review prompt, monorepo package policy를 함께 정리할 수 있습니다.

실습 결과

이 글은 작은 npm workspace 흐름으로 확인했습니다. Changesets 초기화, changeset 작성, changeset status, release PR 설계, publish guardrail 검토를 기준으로 구성했습니다. Claude Code는 diff 기반 release note 초안에는 강하지만 SemVer 단독 판단은 불안정합니다. “왜 breaking change가 아닌지 설명하라”고 시키면 잘못된 minor 또는 patch 판단을 더 빨리 발견할 수 있었습니다.

#Claude Code #Changeset #version management #monorepo #release
무료

무료 PDF: Claude Code 치트시트

이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.

개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.

Masa

작성자 소개

Masa

Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.