콘텐츠로 이동

플러그인 API 레퍼런스

플러그인 시스템을 사용하면 핵심 publish 파이프라인을 포크하지 않고 pubm을 확장할 수 있습니다.

export interface PubmPlugin {
name: string;
registries?: PackageRegistry[];
ecosystems?: Ecosystem[];
hooks?: PluginHooks;
commands?: PluginCommand[];
credentials?: (ctx: PubmContext) => PluginCredential[];
checks?: (ctx: PubmContext) => PluginCheck[];
}
  • credentials - 이 플러그인에 필요한 토큰 목록을 반환합니다. pubm은 초기화 중 한 번 호출해서 누락된 토큰을 프롬프트하고, 환경 변수에 주입하며, --ci-prepare 실행 시 GitHub Secrets와 동기화합니다.
  • checks - 핵심 prerequisite/condition 단계와 함께 실행할 preflight check 목록을 반환합니다. 각 check는 phase 필드로 실행 시점을 선언합니다.
export interface PluginHooks {
// 라이프사이클 훅
beforeTest?: HookFn;
afterTest?: HookFn;
beforeBuild?: HookFn;
afterBuild?: HookFn;
beforeVersion?: HookFn;
afterVersion?: HookFn;
beforePublish?: HookFn;
afterPublish?: HookFn;
beforePush?: HookFn;
afterPush?: HookFn;
afterRelease?: AfterReleaseHookFn;
onError?: ErrorHookFn;
onSuccess?: HookFn;
// asset pipeline 훅
resolveAssets?: AssetPipelineHooks["resolveAssets"];
transformAsset?: AssetPipelineHooks["transformAsset"];
compressAsset?: AssetPipelineHooks["compressAsset"];
nameAsset?: AssetPipelineHooks["nameAsset"];
generateChecksums?: AssetPipelineHooks["generateChecksums"];
uploadAssets?: AssetPipelineHooks["uploadAssets"];
}

여섯 개의 훅으로 플러그인이 release asset 파이프라인의 각 단계를 가로챌 수 있습니다. 이 훅들은 build 단계와 GitHub Release 업로드 사이에서 실행됩니다.

Hook실행 시점입력 → 출력
resolveAssetsglob 매칭 직후ResolvedAsset[]ResolvedAsset[]
transformAssetasset별, 압축 전ResolvedAssetTransformedAsset | TransformedAsset[]
compressAssetasset별, 내장 압축 대체TransformedAssetCompressedAsset
nameAssetasset별, 압축 후CompressedAssetstring
generateChecksums모든 asset이 이름과 해시를 가진 뒤PreparedAsset[]PreparedAsset[]
uploadAssetsGitHub Release 업로드 후PreparedAsset[]UploadedAsset[]

여러 플러그인이 같은 asset pipeline 훅을 등록하면 등록 순서대로 체인됩니다. uploadAssets는 예외입니다. 각 플러그인은 같은 입력을 독립적으로 받고, 결과는 모두 이어 붙입니다.

전체 시그니처, 예제, 조합 규칙은 Asset Pipeline Hooks에서 확인합니다.

type HookFn = (ctx: PubmContext) => Promise<void> | void;
type ErrorHookFn = (ctx: PubmContext, error: Error) => Promise<void> | void;
type AfterReleaseHookFn = (
ctx: PubmContext,
releaseCtx: ReleaseContext,
) => Promise<void> | void;

훅은 현재 파이프라인 컨텍스트를 받습니다.

export interface PubmContext {
readonly config: ResolvedPubmConfig;
readonly options: ResolvedOptions;
readonly cwd: string;
runtime: {
tag: string;
promptEnabled: boolean;
cleanWorkingTree: boolean;
pluginRunner: PluginRunner;
versionPlan?: VersionPlan;
releaseContext?: ReleaseContext;
tempDir?: string;
pluginTokens?: Record<string, string>;
};
}

주요 필드는 다음과 같습니다.

  • ctx.config - 해석된 pubm 설정(packages, registries, plugins, releaseAssets 등)
  • ctx.options - 해석된 CLI 옵션(version, tag, mode, dryRun 등)
  • ctx.cwd - 작업 디렉터리
  • ctx.runtime - 가변 런타임 상태(version plan, temp directory 등)
  • ctx.runtime.pluginTokens - PluginCredential.key를 키로 하는 해석된 플러그인 자격 증명 값 맵입니다. 자격 증명 수집 단계 이후 채워지며 이후 모든 hook에서 사용할 수 있습니다.

플러그인은 publish 파이프라인이 실패할 때 자동으로 실행되는 롤백 액션을 등록할 수 있습니다. 액션은 LIFO(후입선출) 순서로 실행됩니다.

아무 hook 안에서 ctx.runtime.rollback.add()를 사용하여 롤백 액션을 등록합니다.

hooks: {
afterVersion: async (ctx) => {
// Perform side effect
const backup = readFileSync(filePath, "utf-8");
modifyFile(filePath);
// Register rollback to undo it
ctx.runtime.rollback.add({
label: `Restore ${filePath}`,
fn: async () => {
writeFileSync(filePath, backup, "utf-8");
},
});
},
}
속성타입설명
labelstring롤백 중 표시되는 사람이 읽을 수 있는 설명
fn(ctx: PubmContext) => Promise<void>부작용을 되돌리는 비동기 함수
confirmboolean?true이면 TTY 모드에서 실행 전 확인을 요청합니다. CI에서는 자동으로 실행됩니다.

플러그인이 필요로 하는 토큰이나 secret을 선언적으로 설명하는 타입입니다.

export interface PluginCredential {
key: string;
env: string;
label: string;
tokenUrl?: string;
tokenUrlLabel?: string;
ghSecretName?: string;
required?: boolean;
resolve?: () => Promise<string | null>;
validate?: (token: string, task: PluginTaskContext) => Promise<boolean>;
}
필드타입설명
keystringctx.runtime.pluginTokens에서 값을 조회할 때 쓰는 내부 식별자입니다.
envstringCI에서 토큰을 제공하는 환경 변수 이름입니다.
labelstring대화형 프롬프트에 표시되는 사람이 읽을 수 있는 라벨입니다.
tokenUrlstring사용자가 토큰을 생성할 수 있는 선택적 URL입니다.
tokenUrlLabelstringtokenUrl에 표시할 선택적 라벨입니다.
ghSecretNamestring--ci-prepare 동기화 시 사용할 GitHub Secret 이름입니다.
requiredbooleantrue이면 자격 증명을 해석하지 못했을 때 pubm이 오류를 냅니다. 기본값은 true입니다.
resolvefunction선택적 커스텀 resolver입니다. 인자를 받지 않고 Promise<string | null>을 반환합니다. keyring/prompt fallback 전에 호출됩니다.
validatefunction선택적 토큰 검증기입니다. 해석된 토큰과 PluginTaskContext를 받아 false를 반환하면 다시 프롬프트합니다.

해석 순서: env 환경 변수 -> resolve() -> keyring(SecureStore) -> 대화형 프롬프트.

플러그인이 제공하는 preflight check를 설명하는 타입입니다.

export interface PluginCheck {
title: string;
phase: "prerequisites" | "conditions";
task: (ctx: PubmContext, task: PluginTaskContext) => Promise<void> | void;
}
필드타입설명
titlestring작업 목록 UI에 표시되는 라벨입니다.
phase"prerequisites" | "conditions"실행 시점입니다. "prerequisites"는 네트워크 호출 전에, "conditions"는 레지스트리 연결 확인 후에 실행됩니다.
taskfunctioncheck 구현입니다. 오류를 발생시키면 check가 실패합니다.

PluginCheck.task의 두 번째 인자로 전달되는 listr2 비종속 래퍼입니다.

export interface PluginTaskContext {
output: string;
title: string;
prompt<T = unknown>(options: {
type: string;
message: string;
[key: string]: unknown;
}): Promise<T>;
}
  • output - 작업 목록 UI에서 check 제목 아래에 상태 줄을 표시합니다.
  • title - 작업 제목을 동적으로 변경합니다.
  • prompt() - enquirer 프롬프트를 실행합니다. 대화형 모드에서만 사용할 수 있습니다.
const notifyPlugin = {
name: "notify-plugin",
hooks: {
async afterPublish(ctx) {
const label =
ctx.versions && ctx.versions.size > 0
? [...ctx.versions].map(([name, version]) => `${name}@${version}`).join(", ")
: `v${ctx.version}`;
console.log(`Published ${label}`);
},
},
};
export interface PluginCommand {
name: string;
description: string;
subcommands?: PluginSubcommand[];
}
export interface PluginSubcommand {
name: string;
description: string;
options?: PluginCommandOption[];
action: (args: Record<string, unknown>) => Promise<void>;
}

추가 publish 대상을 넣어야 할 때는 커스텀 레지스트리를 사용합니다. 다른 패키지 타입의 version 읽기/쓰기를 pubm에 가르쳐야 할 때는 커스텀 생태계를 사용합니다.