콘텐츠로 이동

설정

pubm은 의도적으로 CLI 우선 도구지만, 실제 프로젝트는 금방 플래그만으로는 부족해집니다. pubm.config.*는 저장소 수준의 publish 대상, 패키지 레이아웃, 플러그인, changeset 기반 버전 규칙을 두는 곳입니다.

pubm init을 실행해 이 설정 파일을 대화형으로 생성합니다. 마법사는 선택 사항이 아래 표시된 기본값과 다를 때만 설정 파일을 생성합니다.

pubm은 다음 파일 이름을 지원합니다.

  1. pubm.config.ts
  2. pubm.config.mts
  3. pubm.config.cts
  4. pubm.config.js
  5. pubm.config.mjs
  6. pubm.config.cjs

TypeScript 설정 파일도 직접 지원합니다. 로더가 평가 전에 파일을 번들링하므로, 별도의 런타임 트랜스파일 단계는 필요하지 않습니다.

설정 레이어에서 해석되는 기본값은 다음과 같습니다.

export default defineConfig({
versioning: "independent",
branch: "main",
changelog: true,
changelogFormat: "default",
commit: false,
access: "public",
fixed: [],
linked: [],
updateInternalDependencies: "patch",
ignore: [],
tag: "latest",
contents: ".",
saveToken: true,
releaseDraft: true,
releaseNotes: true,
rollback: {
strategy: "individual",
dangerouslyAllowUnpublish: false,
},
packages: [{ path: "." }],
validate: {
cleanInstall: true,
entryPoints: true,
extraneousFiles: true,
},
snapshotTemplate: "{tag}-{timestamp}",
locale: "en",
});

pubm은 각 패키지 디렉터리의 매니페스트 파일을 검사해 레지스트리를 매핑합니다.

매니페스트추론되는 레지스트리
package.jsonnpm
jsr.jsonjsr
deno.json / deno.jsoncjsr
Cargo.tomlcrates

npm에는 추가 규칙이 두 개 있습니다.

  • package.jsonpublishConfig.registry가 있으면 npm 대신 해당 커스텀 URL을 사용합니다.
  • publishConfig가 없을 때는 .npmrc 레지스트리가 npm을 대체합니다.
  • 타입: "independent" | "fixed"
  • 기본값: "independent"

멀티 패키지 저장소에서 버전이 어떻게 배정되는지 제어합니다.

  • 타입: string
  • 기본값: "main"

가드된 릴리스 실행 동안 HEAD가 일치해야 하는 브랜치입니다.

  • 타입: PackageConfig[]
  • 기본값: [{ path: "." }]

배포 가능한 패키지를 명시합니다. 레지스트리는 패키지별로 덮어쓰지 않는 한 매니페스트 파일에서 추론됩니다.

  • 타입: PubmPlugin[]
  • 기본값: []

훅, 명령, 레지스트리, 생태계를 추가할 수 있는 플러그인을 등록합니다.

  • 타입: string[][]
  • 기본값: []

항상 같은 버전으로 맞춰야 하는 패키지 그룹입니다.

  • 타입: string[][]
  • 기본값: []

가장 높은 bump type을 공유해야 하는 패키지 그룹입니다.

  • 타입: string[]
  • 기본값: []

워크스페이스 탐지에서 제외할 패키지 이름 또는 경로입니다.

  • 타입: string
  • 기본값: "latest"

publish 실행의 기본 dist-tag입니다.

  • 타입: string
  • 기본값: "."

릴리스 파이프라인을 실행하기 전에 chdir할 디렉터리입니다.

  • 타입: boolean
  • 기본값: true

지원되는 레지스트리 토큰을 로컬 머신에서 재사용하도록 저장할지 여부입니다.

  • 타입: boolean
  • 기본값: true

publish 흐름이 GitHub Release를 만들지 여부입니다. 비활성화하면 release 단계는 완전히 건너뜁니다.

  • 타입: string[]
  • 기본값: []

버전이 올라가고 배포는 되지만 git 태그 생성과 GitHub Release 초안에서는 제외할 패키지를 지정하는 glob 패턴입니다. versioning"independent"일 때만 적용됩니다.

레지스트리에는 배포하지만 단독 릴리스로 노출되지 않아야 하는 내부 빌드 산출물(예: 플랫폼별 바이너리)에 사용합니다.

export default defineConfig({
versioning: "independent",
excludeRelease: ["packages/cli/platforms/*"],
packages: [
{ path: "packages/core" },
{ path: "packages/cli" },
{ path: "packages/cli/platforms/*" },
],
});
  • 타입: ValidateConfig

이 필드들은 공개 스키마의 일부지만, 아직 모든 publish 경로에서 활성 토글로 동작하지는 않습니다. 런타임 스위치가 아니라 타입이 있는 설정 표면으로 보아야 합니다.

  • 타입: string
  • 기본값: "{tag}-{timestamp}"

pubm --snapshot이 임시 버전 문자열을 만들 때 사용하는 템플릿입니다.

사용 가능한 템플릿 변수는 다음과 같습니다.

  • {base}: 매니페스트에 있는 현재 패키지 버전
  • {tag}: snapshot 태그, 기본값은 snapshot
  • {timestamp}: YYYYMMDDTHHmmss 형식의 UTC 타임스탬프
  • {commit}: 현재 git 커밋 SHA

fixed 버전 관리를 사용하는 모노레포 프로젝트에서는 첫 번째 패키지의 버전을 {base}로 사용하여 템플릿이 한 번 적용됩니다. independent 버전 관리에서는 각 패키지가 자신의 {base}를 사용하여 스냅샷 버전을 생성합니다.

  • 타입: boolean
  • 기본값: false

version bump 커밋을 베이스 브랜치에 직접 push하는 대신 pull request를 생성합니다. 활성화하면 pubm이 pubm/version-packages-* 브랜치를 만들고 push한 뒤 PR을 엽니다. PR이 병합되면 기존 릴리스 워크플로가 정상적으로 트리거됩니다.

보호된 브랜치로의 직접 push가 실패할 경우 자동으로 PR 모드로 폴백합니다.

  • 타입: "en" | "ko" | "zh-cn" | "fr" | "de" | "es"
  • 기본값: "en"

CLI 출력 언어입니다. --locale 플래그 또는 PUBM_LOCALE 환경 변수로도 설정할 수 있습니다. 적용 우선순위: --locale 플래그 → PUBM_LOCALE 환경 변수 → config → 시스템 로케일 → "en".

publish 실패 시 롤백 동작을 제어합니다.

타입기본값설명
strategy"individual" | "all""individual"롤백 단위입니다. 더 이상 사용되지 않는 최상위 rollbackStrategy를 대체합니다.
dangerouslyAllowUnpublishbooleanfalse비-TTY(CI) 환경에서 롤백 중 레지스트리 unpublish/yank를 허용합니다. unpublish 후에도 npm은 버전 번호를 영구적으로 예약합니다. 재사용할 수 없습니다.
export default defineConfig({
rollback: {
strategy: "individual",
dangerouslyAllowUnpublish: true, // CI에서 활성화
},
});

더 이상 사용되지 않는 최상위 rollbackStrategy 필드는 계속 동작하며 rollback.strategy로 매핑됩니다. 둘 다 설정된 경우 rollback.strategy가 우선합니다.

현재 런타임 동작은 다음과 같습니다.

  • config는 packagesplugins의 저장소 기본값을 제공합니다.
  • versioning, fixed, linked 같은 버전 관련 config는 changeset 흐름에서 사용됩니다.
  • CLI 플래그는 실행별 publish 동작을 계속 제어합니다.
  • 레지스트리는 매니페스트에서 추론되며, packages[].registries가 그 추론을 덮어씁니다.

특정 레지스트리로 한 번만 publish하려면:

Terminal window
pubm --registry npm --tag beta

워크스페이스나 혼합 언어 저장소에서는 패키지를 명시적으로 선언합니다. 레지스트리는 각 패키지의 매니페스트 파일에서 추론됩니다.

import { defineConfig } from "@pubm/core";
export default defineConfig({
versioning: "independent",
packages: [
{
path: "packages/core",
},
{
path: "packages/cli",
registries: ["npm"],
},
{
path: "crates/pubm-rs",
},
],
});

다음 경우에는 명시적 패키지 설정이 좋습니다.

  • 자동 탐지된 워크스페이스 중 일부만 publish하고 싶을 때
  • JavaScript와 Rust 패키지가 같은 저장소에 함께 있을 때
  • 추론된 레지스트리를 덮어쓰거나 private registry를 추가해야 할 때

패키지 수준 항목의 구조는 다음과 같습니다.

interface PackageConfig {
path: string;
registries?: Array<"npm" | "jsr" | "crates" | PrivateRegistryConfig>;
ecosystem?: "js" | "rust";
buildCommand?: string;
testCommand?: string;
}
interface PrivateRegistryConfig {
url: string;
token: { envVar: string };
}

registries는 추론이 충분하지 않거나, 기본 제공 레지스트리와 함께 private registry를 추가해야 할 때만 사용합니다.

packages: [
{
path: "packages/a",
registries: [
"npm",
{ url: "https://npm.internal.com", token: { envVar: "INTERNAL_NPM_TOKEN" } },
],
},
];

각 패키지는 자체 버전과 태그를 가집니다.

export default defineConfig({
versioning: "independent",
});

영향받는 모든 패키지가 하나의 버전을 공유합니다.

export default defineConfig({
versioning: "fixed",
});

대부분의 패키지는 독립적으로 유지하면서, 선택한 패키지만 함께 움직이게 할 수도 있습니다.

export default defineConfig({
versioning: "independent",
fixed: [["@acme/core", "@acme/react"]],
linked: [["@acme/cli", "@acme/config"]],
});
  • fixed: 그룹 안의 모든 패키지가 정확히 같은 버전이 됩니다.
  • linked: 가장 높은 bump type이 그룹 전체에 전파됩니다.

스냅샷은 preview 릴리스나 브랜치별 검증에 적합합니다.

export default defineConfig({
snapshotTemplate: "{tag}-{timestamp}",
});

예시 출력:

  • 0.4.1-snapshot-20260312T102233

plugins 배열을 통해 플러그인을 추가합니다.

import { defineConfig } from "@pubm/core";
import { externalVersionSync } from "@pubm/plugin-external-version-sync";
export default defineConfig({
plugins: [
externalVersionSync({
targets: [
{
file: "README.md",
pattern: /pubm@([\\w.-]+)/,
},
],
}),
],
});

훅 순서, 명령 등록, 커스텀 레지스트리 지원은 Plugins API Reference에서 확인합니다.

패키지에 package.jsonjsr.json (또는 deno.json / deno.jsonc)이 있으면 레지스트리는 자동 추론됩니다. 설정 파일은 필요하지 않습니다. pubm.config.ts는 선택 사항입니다. 기본값을 덮어써야 할 때만 만듭니다. 예를 들면 커스텀 브랜치, 플러그인, release assets 등이 있습니다.

package.json만 있는 패키지는 npm으로 해석됩니다. 덮어쓰려는 경우가 아니라면 registries를 명시할 필요가 없습니다.

import { defineConfig } from "@pubm/core";
export default defineConfig({
versioning: "fixed",
packages: [
{ path: "packages/web" },
{ path: "packages/server" },
],
});
import { defineConfig } from "@pubm/core";
export default defineConfig({
versioning: "independent",
packages: [
{ path: "packages/sdk" },
{ path: "crates/sdk-core" },
],
});

releaseAssets는 각 GitHub Release에 첨부할 바이너리 산출물을 선언합니다. 대부분의 경우 단순한 glob 문자열만으로 충분합니다.

import { defineConfig } from "@pubm/core";
export default defineConfig({
releaseAssets: [
"platforms/*/bin/mytool",
],
});
  • 타입: "tar.gz" | "zip" | "tar.xz" | "tar.zst" | false | Record<string, CompressFormat>
  • 기본값: OS-aware 자동 감지 (windowszip, 그 외는 tar.gz)

전역 기본 압축 형식입니다. releaseAssets 안의 그룹이나 파일 수준에서 덮어쓸 수 있습니다.

export default defineConfig({
// Windows는 zip, 그 외는 tar.gz 사용
compress: { windows: "zip" },
releaseAssets: [
"platforms/*/bin/mytool",
],
});
  • 타입: (string | ReleaseAssetGroupConfig)[]
  • 기본값: undefined (첨부할 자산 없음)

각 항목은 glob 문자열이거나, 파일·압축·이름을 명시적으로 제어하는 객체입니다.

releaseAssets: [
// 문자열: glob, 완전 자동
"platforms/*/bin/mytool",
// 객체: 그룹별 설정을 명시
{
packagePath: "packages/cli", // 모노레포: 이 패키지의 release에 연결
files: [
"platforms/*/bin/mytool",
{ path: "dist/*.dmg", compress: false, name: "MyTool-{version}-{os}" },
],
compress: "tar.gz", // 그룹 기본값
name: "{name}-{platform}", // 그룹 이름 템플릿
},
]

압축 cascade 규칙, 이름 템플릿 변수, 사용 사례 예시는 Release Assets에서 확인합니다.

pubm changesets version.pubm/changesets/의 changeset 파일과 conventional commit 메시지, 두 가지 소스에서 버전 bump를 해결할 수 있습니다. 어떤 소스가 활성화될지, 커밋 타입이 bump 레벨에 어떻게 매핑될지를 제어할 수 있습니다.

  • 타입: "all" | "changesets" | "commits"
  • 기본값: "all"

pubm changesets version이 버전 bump를 계산할 때 읽을 소스를 제어합니다.

동작
"all"changeset이 있는 패키지에는 changeset을 사용합니다. 보류 중인 changeset이 없는 패키지에는 conventional commits로 폴백합니다.
"changesets".pubm/changesets/ 파일만 읽습니다. Conventional commits는 무시됩니다.
"commits"Conventional commit 메시지만 읽습니다. Changeset 파일은 무시됩니다.

커밋 타입 접두사가 semver bump 레벨에 어떻게 매핑되는지 설정합니다. versionSources"all" 또는 "commits"일 때만 적용됩니다.

export default defineConfig({
versionSources: "all",
conventionalCommits: {
types: {
// 기본적으로 무시되는 타입 추가
refactor: "patch",
docs: "patch",
},
},
});

기본 매핑은 다음과 같습니다.

커밋 타입Bump
featminor
fixpatch
perfpatch

footer에 BREAKING CHANGE가 있거나 ! 접미사(예: feat!:)를 사용한 커밋은 타입 매핑에 관계없이 항상 major bump가 발생합니다.

매핑에 나열되지 않은 커밋 타입(예: chore, docs, test, ci, style, refactor)은 bump 계산 시 무시됩니다. types 객체에서 어떤 타입이든 재정의할 수 있습니다 — 예를 들어 refactor: "patch"는 refactor 커밋을 patch bump로 처리합니다.

  • 패키지 그룹이나 혼합 레지스트리가 필요하면 Monorepo 가이드를 사용합니다.
  • 설정이 커스텀 플러그인을 등록한다면 Plugins API Reference를 사용합니다.
  • 바이너리와 아카이브를 GitHub Releases에 첨부하려면 Release Assets 가이드를 사용합니다.
  • Conventional commit 폴백 동작에 대한 자세한 내용은 Changesets 가이드를 참조합니다.