跳转到内容

Plugins API 参考

插件系统让你可以在不 fork 核心发布流程的前提下扩展 pubm

export interface PubmPlugin {
name: string;
registries?: PackageRegistry[];
ecosystems?: Ecosystem[];
hooks?: PluginHooks;
commands?: PluginCommand[];
credentials?: (ctx: PubmContext) => PluginCredential[];
checks?: (ctx: PubmContext) => PluginCheck[];
}
  • credentials - 返回这个插件需要的 token 列表。pubm 会在初始化时调用一次,用来提示缺失的 token、注入环境变量,并在执行 --ci-prepare 时同步到 GitHub Secrets。
  • checks - 返回与核心 prerequisite/condition 阶段一起运行的 preflight check。每个 check 通过 phase 字段声明执行时机。
export interface PluginHooks {
// 生命周期 hooks
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;
// 资产流水线 hooks
resolveAssets?: AssetPipelineHooks["resolveAssets"];
transformAsset?: AssetPipelineHooks["transformAsset"];
compressAsset?: AssetPipelineHooks["compressAsset"];
nameAsset?: AssetPipelineHooks["nameAsset"];
generateChecksums?: AssetPipelineHooks["generateChecksums"];
uploadAssets?: AssetPipelineHooks["uploadAssets"];
}

六个 hooks 让插件可以拦截发布资产流水线的每个阶段。它们运行在 build 步骤和上传到 GitHub Release 之间。

Hook运行时机输入 → 输出
resolveAssetsglob 匹配之后ResolvedAsset[]ResolvedAsset[]
transformAsset每个资产、压缩之前ResolvedAssetTransformedAsset | TransformedAsset[]
compressAsset每个资产,替换内建压缩TransformedAssetCompressedAsset
nameAsset每个资产,压缩之后CompressedAssetstring
generateChecksums所有资产完成命名和哈希之后PreparedAsset[]PreparedAsset[]
uploadAssetsGitHub Release 上传之后PreparedAsset[]UploadedAsset[]

当多个插件注册同一个资产流水线 hook 时,它们会按注册顺序串联。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;

Hooks 会接收当前的流程上下文:

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、临时目录等)
  • ctx.runtime.pluginTokens:以 PluginCredential.key 为键的已解析插件凭证值映射。它会在凭证收集步骤之后填充,后续所有 hooks 都能用。

插件可以注册回滚操作,当发布流水线失败时会自动执行。操作按 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 中自动执行。

用于声明插件所需 token 或 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>;
}
字段类型说明
keystring用于在 ctx.runtime.pluginTokens 中查找值的内部标识符。
envstring在 CI 中提供该 token 的环境变量名。
labelstring在交互式提示中展示的人类可读标签。
tokenUrlstring用户可创建该 token 的可选 URL。
tokenUrlLabelstringtokenUrl 的可选展示标签。
ghSecretNamestring--ci-prepare 同步时应写入的 GitHub Secret 名称。
requiredbooleantrue 时,如果无法解析该凭证,pubm 会报错。默认值为 true
resolvefunction可选的自定义 resolver,不接收参数,返回 Promise<string | null>。会在 keyring/prompt fallback 之前调用。
validatefunction可选的 token 校验器。接收已解析 token 和 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" 在确认 registry 连通性之后运行。
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 prompt,仅在交互模式下可用。
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>;
}

当你需要额外的发布目标时,使用自定义 registry。当你需要让 pubm 学会读写另一种 package 类型的版本时,使用自定义 ecosystem。