news 2026/9/12 6:53:38

Backstage Scaffolder 如何为自定义 Action 启用并测试 dry run?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Backstage Scaffolder 如何为自定义 Action 启用并测试 dry run?

Backstage Scaffolder 如何为自定义 Action 启用并测试 dry run?

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

如果你写了一个自定义 Scaffolder action(比如调用 GitHub 创建 webhook、写代码仓库的 action),直接跑模板会立刻产生真实副作用,无法安全地验证模板逻辑。Backstage 的 Scaffolder 提供了 dry run(空跑)机制:在不真正执行外部操作的前提下模拟 action 的运行过程,并返回执行日志与生成的工作区文件。本文的完整路径是:在 action 声明上启用 dry run → 在 handler 中处理 dry run 分支 → 为分支写单元测试 → 通过 dry-run API 或 contrib 提供的命令行工具做一次端到端验证。

工作机制:isDryRun 何时为 true

ActionContext上的isDryRun字段有一个关键限制:只有当 action 被标记为支持 dry run 时,它才会为 true(见 types.ts 中isDryRun的注释)。也就是说,如果 action 没有声明supportsDryRun: true,即使整个模板走的是 dry-run 流程,handler 里的ctx.isDryRun也不会成立,你必须显式启用。

dry run 的执行入口在后端 createDryRunner.ts:它把请求携带的模板目录内容解包到临时目录,以isDryRun: true驱动工作流执行所有步骤,并在末尾附加一个dry-run:extract步骤把工作区序列化回响应,最后清理临时目录。

第一步:在 action 上声明 supportsDryRun

在你定义 action 行为的函数里,给createTemplateAction的配置对象加上supportsDryRun: true

export function exampleAction() { return createTemplateAction<{ example: string; }>({ id: 'action:example', description: 'Example action', schema: { input: { type: 'object', properties: { example: { title: 'example', type: 'string', }, }, }, }, supportsDryRun: true, async handler(ctx) { ... }, }); }

其中iddescriptionschema.input换成你的 action 实际的标识与输入 schema;...是你 handler 中已有的业务逻辑。这是唯一的“启用”动作,不需要其他后端配置。

第二步:在 handler 中处理 dry run 分支

声明之后,在 handler 里对ctx.isDryRun做检查。检查命中时执行 dry run 场景下期望的行为(官方文档给出的示例是打印日志后直接返回,也可以输出非敏感的输入信息),避免走到真实副作用的逻辑:

async handler(ctx) { ... // If this is a dry run, log and return if (ctx.isDryRun) { ctx.logger.info(`Dry run complete`); return; } ... }

要点:return必须放在所有会产生外部副作用的调用之前。dry run 的意义就是“模拟而不变更环境”,handler 中任何在检查之后的真实 API 调用都不应被执行。

第三步:为 dry run 分支写单元测试

官方文档要求为 dry run 分支补充测试。示例中...mockContext是你测试文件里已有的模拟上下文对象,input按该 action 的输入 schema 填入,expect(...)断言“action 没有执行”(例如断言某个被 mock 的外部客户端方法未被调用):

it('should not perform action during dry run', async () => { ... // Create the context object with the necessary properties for a dry run const ctx = { ...mockContext, isDryRun: true, input: { ... }, }; // Call the handler with the context await action.handler(ctx); expect(...); });

这段测试直接调用action.handler(ctx),不依赖运行中的 Backstage 实例,适合放进 action 所属模块现有的 Jest 测试文件。

第四步:调用 dry-run API 做端到端验证

单元测试通过只代表分支逻辑正确,完整验证要走 Scaffolder 的 dry-run 接口:POST /api/scaffolder/v2/dry-run(接口定义见 openapi.yaml 中的DryRun操作)。

请求体需要四个字段(templatevaluesdirectoryContents必填,secrets可选):

{ "template": { "apiVersion": "backstage.io/v1beta3", "kind": "Template", "metadata": { "name": "my-template" }, "spec": { "steps": [] } }, "values": {}, "directoryContents": [ { "path": "template.yaml", "base64Content": "<template.yaml 的 base64>" } ] }

各字段的用途:template是完整的 Template 实体(会被校验是否为合法的 template),values是模板参数的取值,directoryContents是模板目录文件的 base64 内容,secrets是键值均为字符串的机密。注意上面 JSON 仅为字段结构示意,template的具体内容必须是你真实的模板实体。

路由侧的处理逻辑(见 router.ts)包含两个前置判断,可据此排查请求失败:

  • 权限:请求需要同时满足taskCreatePermissiontemplateDryRunPermission。如果你的部署启用了后端权限(backend permissions),匿名或无权限的调用会被拒绝;
  • 参数校验:values不匹配模板spec.parameters时,接口返回 400 并在响应体中给出errors字段,提示“Could not execute dry run”。

成功时(200)返回DryRunResult:包含log(每个步骤的日志消息,含stepIdstatus)、directoryContents(dry run 结束时工作区中的文件)和output。判断方式:检查log中你的 action 是否打出了 dry run 分支的日志(如Dry run complete),且没有发生真实外部变更。

可选:用 contrib 的 scaffolder-dry 命令行工具

如果你只想对一个运行中的实例(本地或远端)反复测试模板,可以用 contrib/scaffolder 提供的命令行脚本(实现见 template-testing-dry-run.md)。它对运行中的实例发起上述 dry-run 请求,参数依次为:实例 URL、模板源目录、输入值的 YAML 文件、输出目录:

scaffolder-dry http://localhost:7007/ template-directory values.yml output-directory

其中template-directory是包含template.yaml的模板目录,values.yml是渲染模板所需的输入,output-directory是 dry run 结果文件的落盘位置——该目录内容会由脚本写入,属于预期副作用。如果你使用 backend permissions,需要通过--token传入当前浏览器会话的前端 auth token:

scaffolder-dry --token $FRONTEND_TOKEN http://localhost:7007/ template-directory values.yml output-directory

脚本会把响应中的日志逐条打印到终端,并把directoryContents写入目标目录,方便你直接核对 dry run 生成的文件是否符合预期。

限制与核对清单

  • ctx.isDryRun仅在 action 声明了supportsDryRun: true时为 true;遗漏声明会导致 dry run 时仍走真实逻辑,这是最常见的配置失误。
  • dry run 只是“模拟而不变更”,不校验外部系统(如 GitHub)的连通性与凭据有效性;handler 中 dry run 分支能覆盖的,就是你在检查之后跳过的那些调用。
  • 端到端验证要求一个正在运行的 Backstage 实例,且调用方具备taskCreatePermissiontemplateDryRunPermission
  • 完整的启用、分支处理与单测写法见 dry-run-testing.md。

【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 6:53:09

企业文件管理软件选型指南与10款产品深度评测

1. 企业文件管理现状与核心痛点作为在IT行业摸爬滚打十多年的老鸟&#xff0c;我见证过太多企业因为文件管理混乱导致的"灾难现场"——市场部把合同存进财务部的共享文件夹、技术部门的设计图纸被误删后无法恢复、异地团队协作时版本混乱到需要人工比对...这些场景每…

作者头像 李华
网站建设 2026/9/12 6:51:41

数字化族谱管理系统:DAG建模与协同编辑技术解析

1. 族谱管理系统的时代需求与行业痛点在中国传统文化语境中&#xff0c;族谱承载着家族血脉传承的历史记忆。随着数字化浪潮席卷各行各业&#xff0c;传统纸质族谱正面临三大核心挑战&#xff1a;首先是信息更新滞后&#xff0c;纸质版本修订周期长、成本高&#xff1b;其次是查…

作者头像 李华
网站建设 2026/9/12 6:50:28

OpenStock实时价格追踪:3分钟跑在自己电脑上的免费行情工具

OpenStock实时价格追踪&#xff1a;3分钟跑在自己电脑上的免费行情工具 【免费下载链接】OpenStock OpenStock is an open-source alternative to expensive market platforms. Track real-time prices, set personalized alerts, and explore detailed company insights — bu…

作者头像 李华
网站建设 2026/9/12 6:50:07

CAN总线故障排查:90%难题卡在物理层,从电压到电阻的实战套路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 6:49:34

Linux wheel组与sudo权限完全指南:从原理到安全配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华