Skip to content

模板与插件

返回总览

当一条 workflow 变成团队内重复出现的模式时,真正有价值的不是再复制一份文件,而是把结构提炼出来

模板适合解决什么问题

模板本质上是 workflow 工厂

适合这类场景

  • 发布流程有固定骨架
  • 部署流程按服务名生成不同实例
  • 故障处理流程按严重级别套出不同步骤组合
ts
import {
  createWorkflowTemplateCatalog,
  defineStep,
  defineSteps,
  defineWorkflowTemplate,
} from 'clack-kit';

const deployTemplate = defineWorkflowTemplate({
  id: 'deploy-service',
  title: '部署服务',
  create(input: { service: string }) {
    return {
      id: `deploy-${input.service}`,
      steps: defineSteps([
        defineStep.text({
          id: 'service',
          message: '服务名',
          defaultValue: input.service,
        }),
      ]),
      title: `部署 ${input.service}`,
    };
  },
});

const catalog = createWorkflowTemplateCatalog([deployTemplate] as const);

插件的四个扩展点

WorkflowPlugin 目前最重要的扩展点有四个

扩展点作用
setup注册自定义步骤处理器
extendContextTools往 context.tools 挂新能力
wrapRenderer包裹默认 renderer
wrapExecutor包裹命令执行器

setup 和 registerStepHandler

自定义步骤类型时,入口在 setup

ts
const plugin = {
  name: 'approval-step',
  setup(api) {
    api.registerStepHandler('approval', async ({ context, step }) => {
      context.note(`审批人:${String(step.approver)}`, '审批步骤');
      return {
        approved: true,
      };
    });
  },
};

这种方式适合把领域步骤抽出来,例如审批、工单、告警确认

extendContextTools 的边界

适合挂那些跨多条 workflow 复用、又不想每次手动 import 的工具函数

例如

  • 读取仓库约定文件
  • 访问团队内部配置
  • 包装一层常用命令

wrapRenderer 和 wrapExecutor

这两个扩展点更偏底层

wrapRenderer

适合统一修改终端表现,例如包一层额外提示、收集埋点或替换局部渲染行为

wrapExecutor

适合统一修改命令执行行为,例如记录额外监控信息、接入另一套命令后端或注入环境变量

executorType 和自定义 executor 的关系

  • executorType 用来选择内置执行器,默认是 node
  • executor 用来完全替换执行器
  • wrapExecutor 包裹的是最终选定的执行器

这三者的优先级关系明确后,执行层扩展就不容易绕乱

模板和插件怎么配合

一个常见组合是

  • 用模板沉淀流程骨架
  • 用插件补统一能力和领域步骤

这样做的好处是

  • 模板负责结构复用
  • 插件负责运行时能力复用
  • 两者职责分开,改动范围更可控

下一步建议