Backstage v1.51.0-next.3 变更解读:Scaffolder 表单体系升级、AWS Web Identity 凭据与 Catalog 搜索性能重构
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
导读
本文围绕 Backstage 官方仓库发布的 v1.51.0-next.3 预发布版本(docs/releases/v1.51.0-next.3-changelog.md)展开,聚焦本版本中四个最值得关注的变更主题:Scaffolder 表单体系的formDecorators字段转正与 BUI 主题支持、AWS 集成的webIdentityTokenFile凭据获取、Catalog 后端搜索表索引重构与分页语义修复,以及新增的 alpha 版TracingService。读完本文,你将掌握这些新 API 的配置方式、行为变化、升级注意事项,以及每个变更背后对应的源码实现位置,便于在升级到该版本前后进行针对性验证。
说明:本文是基于官方变更日志(changelog)的技术解读文章,所引用的代码与配置均出自当前仓库对应版本的源码与测试,可作为升级评估与二次开发的参考。
一、版本概览与升级入口
v1.51.0-next.3 是 Backstage v1.51.0 发布前的第三个预发布(next)版本,包含多个插件包与核心包的功能新增(Minor Changes)和缺陷修复(Patch Changes)。本次变更中:
- Major Changes(破坏性变更):仅出现在
@backstage/plugin-scaffolder-backend@4.0.0-next.2,即 SecureTemplater 的显式内存管理。 - Minor Changes(功能新增):主要集中在 Scaffolder 系插件、
@backstage/integration-aws-node与@backstage/plugin-catalog-backend。 - 其余大多数包为依赖升级与内部拼写/注释修复。
升级前建议使用官方 Upgrade Helper(将目标版本设为1.51.0-next.3)生成针对性的升级步骤清单,并重点评估第三节中的目录搜索表迁移与第五节中的破坏性分页语义变化。
二、Scaffolder 表单体系升级:formDecorators转正与 BUI 主题
本版本中 Scaffolder 相关的前后端包(@backstage/plugin-scaffolder@1.37.0-next.2、@backstage/plugin-scaffolder-react@1.21.0-next.1、@backstage/plugin-scaffolder-common@2.2.0-next.1、@backstage/plugin-scaffolder-backend@4.0.0-next.2、@backstage/plugin-scaffolder-node@0.13.3-next.2)同步升级,核心变化有三块。
2.1formDecorators字段从实验性转正
Templatespec 上的表单装饰器字段由实验性的EXPERIMENTAL_formDecorators正式更名为formDecorators:
- 后端在模板参数 schema 响应中现在暴露
formDecorators字段,替代原来的EXPERIMENTAL_formDecorators; - 仍声明
spec.EXPERIMENTAL_formDecorators的旧模板会被透明读取,并映射到新字段下,无需立即迁移; - 前端模板向导(template wizard)优先读取新的
spec.formDecorators,未迁移的模板回退到已弃用的EXPERIMENTAL_formDecorators。
在源码层面,plugins/scaffolder-common/src/TemplateEntityV1beta3.ts 中同时保留了新旧两个可选字段,旧字段标注了@deprecated Use spec.formDecorators instead,类型均为{ id: string; input?: JsonObject }[]。
同时,formDecoratorsApiRef、ScaffolderFormDecoratorsApi、DefaultScaffolderFormDecoratorsApi、formDecoratorsApi以及FormDecoratorBlueprint、ScaffolderFormDecorator均由@alpha提升为@public,意味着这些 API 从“可能变更的实验接口”进入稳定公共 API 行列,插件作者可以放心依赖。
此外,表单装饰器的输入处理有了更严格的校验:装饰器运行前,其输入会先按照装饰器上配置的 zod schema 进行解析,.default()声明的默认值会被应用,非法输入会通过错误 API 上报,而不再静默通过。
2.2 Scaffolder 表单的 BUI 主题(实验性)
本版本为 Scaffolder 表单新增了实验性的 BUI(Backstage UI)表单主题。启用后,所有默认字段扩展(field extension)都会渲染为 BUI 变体。提供两种启用方式:
方式一:扩展配置(YAML)
app: extensions: - sub-page:scaffolder/templates: config: enableBackstageUi: true方式二:JSX props
<ScaffolderPage formProps={{ EXPERIMENTAL_theme: 'bui' }} />从 plugins/scaffolder-react/src/components/types.ts 的声明可以看出,EXPERIMENTAL_theme的类型为'mui' | 'bui',即默认的 Material UI 主题与新的 BUI 主题之间可切换。在 plugins/scaffolder-react/src/next/components/Form/BuiTheme 目录下可以看到 BUI 主题的模板(如FieldTemplate、BaseInputTemplate)及其测试用例。
2.3 模板列表页的 groups 分组配置
sub-page:scaffolder/templates扩展新增groups配置字段,可在模板列表页定义模板分组。每个分组包含title和filter谓词;未被任何分组匹配的模板会自动落入追加的 "Other Templates"(其他模板)分组;未配置 groups 时,页面照常渲染单一的 "Templates"(模板)分组。
app: extensions: - sub-page:scaffolder/templates: config: groups: - title: Recommended Services filter: spec.type: service - title: Documentation filter: spec.type: documentation2.4TemplateCard变为可替换组件(Swappable)
新前端系统下,TemplateCard组件现在可以通过注册一个以TemplateCard为目标的SwappableComponentBlueprint来自定义替换。作为可替换实现使用的组件接收TemplateCardComponentProps,其中onSelected是一个绑定到所渲染模板的零参数回调。现有使用方式不受影响。
2.5 SecureTemplater 显式内存管理(Major Changes)
@backstage/plugin-scaffolder-backend的本次 Major Change(提交c78b3b6)为 SecureTemplater 的使用增加了显式的内存管理逻辑,确保模板渲染完成后相关资源能被及时释放。该变更位于 scaffold 任务执行的核心链路中,升级时建议对模板渲染类任务做回归测试。
三、Catalog 后端搜索表重构:索引、去重与分页语义修复
@backstage/plugin-catalog-backend@3.7.0-next.2是本版本中改动密度最高的包,围绕实体搜索(search)表进行了系统性的索引与查询计划优化,其中一项是破坏性变更。
3.1 破坏性变更:/entities/by-query排序分页语义
BREAKING:使用带排序字段的order通过/entities/by-query分页实体时,缺少排序字段的实体现在会同时从结果集和totalItems计数中排除。
变更原因:此前这些实体通过NULLS LAST语义出现在排序结果末尾,但基于游标的分页实际上无法越过第一页触达它们——计数会虚高(over-report)可导航实体的数量。新行为让计数与实际返回结果保持一致,同时移除了排序字段 CTE 中的DISTINCT去重,这是查询规划器按排序顺序使用(key, value, entity_id)索引并在LIMIT处短路的前置条件。
升级注意:存在重复搜索行的安装应在采纳此变更前先完成搜索表去重迁移(见 3.3 小节)。
3.2 排序查询由 search 索引驱动
补丁变更add5d1a重构了实体列表端点:当指定排序字段时,查询由 search-by-key 索引驱动,而非将 search 表侧连接(side-join)到final_entities上。这使得 PostgreSQL 可以按已排序顺序遍历(key, value, entity_id)索引,并在LIMIT处短路。变更日志描述典型宽过滤分页列表的耗时从“秒级”降至“毫秒级”。缺少排序字段的实体仍按NULLS LAST语义出现在排序结果末尾,并以entity_id排序。
3.3 搜索表去重迁移与大库部署建议
补丁变更7445f0f新增了一个迁移,其作用包括:
- 删除
search表中的重复行; - 创建覆盖索引(covering indices)以改善查询性能;
- 在
(entity_id, key, value)上新增UNIQUE约束。
该迁移在大目录上是长耗时迁移:在拥有数百万 search 行的 PostgreSQL 上,每个索引的创建可能需要5–15 分钟。索引创建期间不会阻塞读写,运行旧版本的其他 Pod 可继续正常服务流量;但若 Kubernetes liveness 探针在索引构建完成前杀掉了 Pod,构建进度将丢失,下次启动会重新开始,在大表上可能无限循环。
大型安装建议在部署本版本之前,直接对 PostgreSQL 执行以下 SQL(每个索引构建耗时数分钟,但不阻塞读写;若已提前完成,迁移会检测到已有索引并跳过全部工作,启动即为瞬时):
-- Step 1: Remove duplicate search rows WITH cte AS ( SELECT ctid, row_number() OVER (PARTITION BY entity_id, key, value) AS rn FROM search ) DELETE FROM search USING cte WHERE search.ctid = cte.ctid AND cte.rn > 1; -- Step 2: Create new indices (run each separately) CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS search_entity_key_value_idx ON search (entity_id, key, value); CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_value_entity_idx ON search (key, value, entity_id); CREATE INDEX CONCURRENTLY IF NOT EXISTS search_facets_covering_idx ON search (key, original_value, entity_id) WHERE original_value IS NOT NULL; -- Step 3: Drop old indices that are no longer needed DROP INDEX CONCURRENTLY IF EXISTS search_key_value_idx; DROP INDEX CONCURRENTLY IF EXISTS search_key_original_value_idx;这三个新索引的命名与用途可以在仓库的迁移测试(plugins/catalog-backend/src/tests/migrations.test.ts)与查询负载测试基线(plugins/catalog-backend/src/tests/performance/query-battery/baseline.md)中找到佐证:例如search_key_value_entity_idx被用于以key='metadata.name'或kind=component等条件驱动索引扫描并配合LIMIT短路。
此外,该提交还修复了buildEntitySearch对具有重复数组值实体的重复输出问题,并为syncSearchRows增加了ON CONFLICT DO UPDATE,使并发拼接(stitching)竞态被优雅处理。
3.4 facets 聚合与过滤查询的性能优化
387ea7d:实体 facets 聚合从COUNT(DISTINCT entity_id)简化为COUNT(*)。(entity_id, key, value)上的唯一约束保证每个实体在每个 search 行分组中至多出现一次,使DISTINCT不再必要,数据库可采用更简单的聚合计划。3f55b73:带过滤条件的 facets 端点性能提升。过滤后的实体集合改为通过 inner join 与 search 表组合,替代WHERE entity_id IN (subquery)写法;结果不变,但在大目录上查询规划器能选择显著更廉价的计划——变更日志给出的实测提升范围约为“已经很快的场景 1.2×,高基数 facets 上 7× 以上”。
3.5catalog_entities_count指标优化
补丁变更ccbad9d改善了catalog_entities_count指标的性能。此前 legacy Prometheus 与 OpenTelemetry 两类可观测 gauge 在每次指标抓取时各自对search表执行一次按 kind 的计数查询;在大目录上,查询堆积速度可能超过完成速度,争抢数据库缓冲并拖慢数据库。
现在两个回调共享同一次查询结果(带短时进程内 TTL 缓存),且底层查询改为从final_entities而非search读取,避免了此前占主导的 bitmap heap scan。发出的标签(labels)与数值保持不变。相关实现见 plugins/catalog-backend/src/database/metrics.ts。
3.6 其他修复
cde3643:为unregister-entityMCP action 的type参数补充了缺失的描述。
四、AWS 集成:基于 OIDC Web Identity Token 文件的凭据获取
@backstage/integration-aws-node@0.2.0-next.1新增webIdentityTokenFile配置项,允许 Backstage 通过 OIDC Web Identity 机制获取 AWS 临时凭据。
4.1 新增配置项与行为
AwsIntegrationAccountConfig与AwsIntegrationDefaultAccountConfig均新增了webIdentityTokenFile字段——即磁盘上包含 OIDC web-identity token 的文件路径。类型定义见 packages/integration-aws-node/src/config.ts。
当该字段与roleName同时设置时,DefaultAwsCredentialsManager通过fromTokenFile(AWS SDK 的AssumeRoleWithWebIdentity封装)获取凭据:将文件内容作为 web identity token,每次凭据刷新时都会重新读取该文件。实现位于 packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts,调用fromTokenFile({ webIdentityTokenFile, roleArn, roleSessionName: 'backstage', ... }),其中roleArn由accountId、partition(默认aws)与roleName拼接而成。
这非常适合 Kubernetes 等环境中的IRSA / workload identity场景:Pod 挂载的 OIDC token 文件会周期性轮转,本特性保证每次刷新凭据时都读取最新 token,无需静态密钥。
4.2 配置校验规则
配置校验器(packages/integration-aws-node/src/config.ts)对webIdentityTokenFile的组合使用有严格要求,以下组合会被拒绝:
| 非法组合 | 原因 |
|---|---|
webIdentityTokenFile+accessKeyId/secretAccessKey | 静态凭据与 web identity 只能二选一 |
webIdentityTokenFile+profile | 配置文件凭据与 web identity 只能二选一 |
webIdentityTokenFile但未设置roleName | AssumeRoleWithWebIdentity必须指定要扮演的 IAM 角色 |
webIdentityTokenFile+externalId | AssumeRoleWithWebIdentity不支持 external ID |
其中“未设置roleName”与“同时设置externalId”两条规则同样作用于AwsIntegrationDefaultAccountConfig的默认账户配置(packages/integration-aws-node/src/config.ts)。DefaultAwsCredentialsManager内部也保留了同样的防御性校验(packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts),即使绕过配置解析直接构造对象也会被拦截。
4.3 凭据解析优先级
结合getSdkCredentialProvider中的逻辑(packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts),单账户凭据的解析顺序为:
- 带 web identity token 文件的 AssumeRole(无静态凭据);
- 带静态凭据的 AssumeRole;
- 使用主账户凭据的 AssumeRole;
- 静态凭据;
- profile 凭据;
- 默认 AWS SDK 凭据链。
该优先级也完整记录在源码注释中,可作为排查凭据解析问题的依据。
五、TracingService:跨插件的统一链路追踪接口(alpha)
@backstage/backend-defaults@0.17.1-next.2与@backstage/backend-plugin-api@1.9.1-next.1新增了 alpha 版TracingService,为跨 Backstage 插件发射 trace span 提供统一接口。同时@backstage/backend-test-utils@1.11.3-next.2增加了对应的 tracing service mock(提交7fb12b8),便于在测试中注入。
由于该接口当前处于 alpha 阶段,接入时建议关注后续版本中 API 形状的演进,并在插件边界保持抽象,以降低未来迁移成本。
六、UI 与 App 层变更
6.1@backstage/ui@0.15.0-next.3
4bb649d:修复带行选择的 Table 在祖先元素上产生幽灵滚动高度(phantom scroll height)的问题——通过为视觉隐藏的 checkbox 输入建立包含块(containing block)实现。受影响组件:Table、TableRoot。d726bcd:新增DatePicker组件——组合日期输入框与日历弹出层,基于 React Aria 构建,支持完整的键盘与屏幕阅读器无障碍访问,并全程使用 BUI 设计令牌(含通过 bg consumer 模式的自动递增背景)。
6.2@backstage/plugin-app@0.4.6-next.2
app/routes的重定向配置现在支持在to目标中进行路径参数替换。from路径中捕获的命名参数(:userId)与 splat 参数(*)会在导航前替换到to字符串中:
app: extensions: - app/routes: config: redirects: - from: /users/:userId to: /profile/:userId - from: /old-docs to: /docs/*6.3 其他修复
@backstage/plugin-auth与@backstage/plugin-auth-backend(4f62755):改进 MCP 授权的 OAuth 同意对话框,展示更多客户端详情,包括 CIMD 客户端的客户端元数据 host、元数据 URL、回调 URL 与请求的 scopes。@backstage/plugin-catalog@2.0.5-next.1(728629c):修复访问实体页未知子路径(如/catalog/default/component/foo/blob)时静默渲染首个可用路由的问题,现在会显示标准的 not-found 页面。@backstage/plugin-kubernetes-react@0.5.19-next.1(e68cb8a):KubernetesBackendClient新增可选的clustersCacheTtlMs,在指定时长内缓存getClusters()响应,避免多个代理调用在短时间内解析集群认证时重复发起/clusters请求。@backstage/create-app@0.8.3-next.3(14e2056):应用模板中的 Jest 版本范围固定为~30.2.0,防止自动升级到需要 Node.js v24.9+ 的 Jest 30.4.x(后者会在 Node 22 上破坏测试)。- 多个包(
scaffolder-backend、catalog-backend-module-gitlab、kubernetes-backend)完成了内部代码拼写错误修复(1ecc3ca)。
七、升级检查清单
结合以上变更,升级到 v1.51.0-next.3 时建议按以下顺序检查:
- Catalog 搜索表:若目录较大,先在部署前执行 3.3 小节的 SQL(去重 + 三个新索引 + 删除旧索引),并评估
/entities/by-query排序分页的破坏性语义是否影响现有调用方(3.1)。 - Scaffolder:验证
EXPERIMENTAL_formDecorators模板在升级后仍能正常工作(2.1);如需 BUI 主题,按 2.2 的两种方式之一启用;检查TemplateCard自定义是否仍兼容(2.4)。 - AWS 集成:如需 workload identity 场景,为账户或
accountDefaults配置webIdentityTokenFile与roleName,注意避开 4.2 中的非法组合。 - 示例与内部包:
example-app、example-app-legacy、example-backend、@internal/scaffolder均随本版本升级依赖,可作为升级后的冒烟验证参照(packages/app、packages/backend)。
结语
v1.51.0-next.3 的变更呈现出两条清晰的演进主线:一是 Scaffolder 表单体系走向成熟——formDecorators转正、BUI 主题落地、模板分组与可替换卡片,开发者可以在不破坏旧模板的前提下逐步迁移;二是 Catalog 后端的数据库层深度优化——以 search 索引重构换取毫秒级的分页与 facets 查询,同时用破坏性语义修正让计数回归真实。配合 AWS OIDC 凭据能力与 alpha 版链路追踪接口,本版本为开发门户的规模化运行与可观测性提供了更扎实的地基。
【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考