Backstage v1.3.0 版本深度解析:Token 安全强化、Catalog Entity Provider 迁移与 Scaffolder 任务管理
2026/9/13 9:53:12 网站建设 项目流程

Backstage v1.3.0 版本深度解析:Token 安全强化、Catalog Entity Provider 迁移与 Scaffolder 任务管理

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

本篇技术指南基于 Backstage 官方 v1.3.0 变更日志(docs/releases/v1.3.0-changelog.md),系统性梳理该版本引入的破坏性变更与核心新能力:ServerTokenManager强制校验exp声明、Catalog 发现机制从 Processor 向 Entity Provider 迁移(Bitbucket Cloud / Azure DevOps / GitLab)、Scaffolder 任务列表页与 Gerrit 支持、搜索结果的rankdiscover分析事件等。阅读本文后,你将掌握 v1.2.0 → v1.3.0 升级过程中需要处理的全部迁移要点,并能直接复刻各插件的新配置与代码写法。

v1.3.0 版本主题概览

v1.3.0 是 Backstage 在 1.0 系列稳定期的一次重要功能版本,涉及数十个@backstage/*包同步发版,核心主题集中在以下几个方面:

主题领域涉及包关键变化
服务间认证安全@backstage/backend-common@0.14.0破坏性变更:服务端 token 必须携带未过期的exp声明
Catalog 发现机制演进catalog-backend-module-bitbucket-cloud-azure-gitlab新增/补全 Entity Provider,替代传统 Discovery Processor
脚手架任务可观测性@backstage/plugin-scaffolder@1.3.0scaffolder-backend@1.3.0新增/create/tasks任务列表页、listTasksAPI、/v2/tasks路由
搜索与分析plugin-searchplugin-catalogplugin-techdocs搜索结果新增rank,点击事件升级为discover事件
新插件dynatracevaultgithub-pull-requests-board三个全新插件首次发布

下文按"升级必读 → 迁移实操 → 新功能"的顺序展开。

服务端 Token 强制校验exp:v1.3.0 最重要的破坏性变更

@backstage/backend-common@0.14.0的 Minor Changes 中有一条BREAKING声明:所有由ServerTokenManager认证的服务端到服务端(server-to-server)token,现在必须携带尚未过期exp声明。凡是exp缺失或已过期的 token 一律视为无效并抛出错误。

这条变更承接自 v1.2.0 中对"永久 token(perpetual tokens)"的弃用声明,是对该弃用的最终落地。升级后必须注意:

  • 更新所有getToken()的调用方式:每次需要 token 时都重新调用,不要在应用启动时获取一次然后长期存储复用;
  • 由于 token 现在带有过期时间,任何"获取一次、反复使用"的缓存逻辑都会在过期后触发认证失败;
  • 仓库当前代码中仍能看到该管理器的使用痕迹,例如 packages/backend-defaults/CHANGELOG.md 记录的ServerTokenManager.fromConfig(config, ...)构造方式,它是后端默认服务装配中 token 管理的标准入口。

从架构角度看,这一变更让 Backstage 的插件后端之间通信具备了真正的时效性安全边界:即使 token 意外泄露,其有效窗口也受到exp限制,而不是无限期有效。同时它也提醒所有插件作者:token 的获取与使用应当"按需即取",与服务生命周期解耦。

Catalog 发现机制演进:从 Processor 到 Entity Provider

v1.3.0 在 Catalog 后端模块上集中发力,将多个 Git 托管平台的自动发现能力从"处理器(Processor)"模式迁移到"实体提供者(Entity Provider)"模式。后者由调度器(Scheduler)驱动,周期性拉取仓库列表并注册catalog-info.yaml,相比 Processor 具备更明确的配置结构、支持多实例并行与更细粒度的过滤。

新增@backstage/plugin-bitbucket-cloud-common:统一的 Bitbucket Cloud 客户端

该版本新增了通用库@backstage/plugin-bitbucket-cloud-common@0.1.0,提供一个可复用的 Bitbucket Cloud API 客户端。变更日志明确指出:这个客户端可以在所有包之间复用,未来很可能成为承载限流管理等额外能力的公共基础层;客户端部分代码由@openapitools/openapi-generator-cli生成。它被随后发布的新 Entity Provider 模块作为底层依赖引用。

新模块catalog-backend-module-bitbucket-cloud:用 Provider 取代 Discovery Processor

新发布的@backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.0提供了BitbucketCloudEntityProvider,官方定位是BitbucketDiscoveryProcessorBitbucket Cloud(仅限云端)场景下的替代品,明确覆盖原先使用search=true的用例,并可作为完整替代。迁移步骤如下。

迁移前(Processor 模式),在 packages/backend/src/plugins/catalog.ts 中注册处理器,并在app-config.yaml中配置 location:

// packages/backend/src/plugins/catalog.ts builder.addProcessor( BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), );
# app-config.yaml catalog: locations: - type: bitbucket-discovery target: 'https://bitbucket.org/workspaces/workspace-name/projects/apis-*/repos/service-*?search=true&catalogPath=/catalog-info.yaml'

迁移后(Entity Provider 模式)

// packages/backend/src/plugins/catalog.ts builder.addEntityProvider( BitbucketCloudEntityProvider.fromConfig(env.config, { logger: env.logger, schedule: env.scheduler.createScheduledTaskRunner({ frequency: { minutes: 30 }, timeout: { minutes: 3 }, }), }), );
# app-config.yaml catalog: providers: bitbucketCloud: yourProviderId: # identifies your ingested dataset catalogPath: /catalog-info.yaml # default value filters: # optional projectKey: '^apis-.*

源码级配置说明。结合 plugins/catalog-backend-module-bitbucket-cloud/config.d.ts 与 plugins/catalog-backend-module-bitbucket-cloud/src/providers/BitbucketCloudEntityProviderConfig.ts 的解析逻辑,配置项细节如下:

  • workspace必填,指定要发现的 Bitbucket 工作区。注意config.d.ts中该字段被标记为 Required;
  • catalogPath:可选,默认/catalog-info.yaml(常量DEFAULT_CATALOG_PATH定义于配置解析文件中);
  • filters.projectKey/filters.repoSlug:可选正则表达式,分别按项目 Key 与仓库 slug 过滤。底层compileRegExp会自动为模式补全^$锚点(BitbucketCloudEntityProviderConfig.ts),因此无论你写不写锚点,匹配都是整行全匹配语义;
  • schedule:可选,调度定义;也可在代码中通过env.scheduler.createScheduledTaskRunner(...)传入。从 BitbucketCloudEntityProvider.ts 的实现可见,代码与配置二者必须提供其一,否则fromConfig会直接抛出'Either schedule or scheduler must be provided.'异常;
  • pagelen:可选,每页从 Bitbucket API 拉取的结果数,默认 100;
  • 配置支持"单配置变体"(直接写workspace键)与"命名多 Provider 变体"两种形式:当配置顶层存在workspace字段时按default作为 provider id 解析,否则遍历所有子键作为多个独立 provider(见 BitbucketCloudEntityProviderConfig.ts)。

此外,该 Provider 与事件系统集成(源码顶部常量TOPIC_REPO_PUSHTOPIC_REPO_UPDATED,见 BitbucketCloudEntityProvider.ts),可响应仓库推送等事件实现增量发现。

Azure DevOps:AzureDevOpsEntityProvider迁移指南

@backstage/plugin-catalog-backend-module-azure@0.1.4新增AzureDevOpsEntityProvider,作为AzureDevOpsDiscoveryProcessor的替代。迁移前后对比如下。

迁移前,使用azure-discovery类型的 location 与 Processor:

# app-config.yaml catalog: locations: - type: azure-discovery target: https://dev.azure.com/myorg/myproject/_git/service-*?path=/catalog-info.yaml
/* packages/backend/src/plugins/catalog.ts */ import { AzureDevOpsDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-azure'; const builder = await CatalogBuilder.create(env); /** ... other processors ... */ builder.addProcessor(new AzureDevOpsDiscoveryProcessor(env.reader));

迁移后,改用catalog.providers.azureDevOps配置与AzureDevOpsEntityProvider.fromConfig

# app-config.yaml catalog: providers: azureDevOps: anyProviderId: host: selfhostedazure.yourcompany.com # This is only really needed for on-premise user, defaults to dev.azure.com organization: myorg # For on-premise this would be your Collection project: myproject repository: service-* path: /catalog-info.yaml
/* packages/backend/src/plugins/catalog.ts */ import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure'; const builder = await CatalogBuilder.create(env); /** ... other processors and/or providers ... */ builder.addEntityProvider( AzureDevOpsEntityProvider.fromConfig(env.config, { logger: env.logger, schedule: env.scheduler.createScheduledTaskRunner({ frequency: { minutes: 30 }, timeout: { minutes: 3 }, }), }), );

要点:host仅本地部署(on-premise)才需要显式配置,默认为dev.azure.comorganization在本地部署场景对应你的 Collection;repository支持service-*这样的通配符匹配。

GitLab:GitlabDiscoveryEntityProvider与性能优化标志

@backstage/plugin-catalog-backend-module-gitlab@0.1.4新增GitlabDiscoveryEntityProvider(实现见 plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts),替代GitlabDiscoveryProcessor

迁移前

# app-config.yaml catalog: locations: - type: gitlab-discovery target: https://company.gitlab.com/prefix/*/catalog-info.yaml
/* packages/backend/src/plugins/catalog.ts */ import { GitlabDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-gitlab'; const builder = await CatalogBuilder.create(env); /** ... other processors ... */ builder.addProcessor( GitLabDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), );

迁移后

# app-config.yaml catalog: providers: gitlab: yourProviderId: # identifies your dataset / provider independent of config changes host: gitlab-host # Identifies one of the hosts set up in the integrations branch: main # Optional. Uses `master` as default group: example-group # Group and subgroup (if needed) to look for repositories entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml`
/* packages/backend/src/plugins/catalog.ts */ import { GitlabDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab'; const builder = await CatalogBuilder.create(env); /** ... other processors and/or providers ... */ builder.addEntityProvider( ...GitlabDiscoveryEntityProvider.fromConfig(env.config, { logger: env.logger, schedule: env.scheduler.createScheduledTaskRunner({ frequency: { minutes: 30 }, timeout: { minutes: 3 }, }), }), );

注意 Provider 返回的是数组,注册时需用展开运算符...展开。该模块还带了两项值得关注的优化:

  1. 首次查询 GitLab API 时不再携带last_activity_after时间戳;
  2. 新增skipReposWithoutExactFileMatch标志:当仓库中不存在catalog-info.yaml时不再创建 location 对象,从而显著降低 GitLab 返回 404 的请求量:
const processor = GitLabDiscoveryProcessor.fromConfig(config, { logger, skipReposWithoutExactFileMatch: true, });

警告:该新功能不支持在仓库文件路径中使用 glob 通配符。

Scaffolder 增强:任务列表页、listTasksAPI 与 Gerrit 支持

v1.3.0 对 Scaffolder 的改进覆盖前后端,使模板执行任务的可见性与控制能力大幅提升。

新增/create/tasks任务列表页

@backstage/plugin-scaffolder@1.3.0新增/create/tasks页面,用于展示 Scaffolder 已运行的任务,并支持按"当前登录用户"与"全部任务"两种维度过滤。其前端路由定义可见 plugins/scaffolder/src/routes.ts 中的scaffolderListTaskRouteRef(路径为/tasks,挂在/create之下构成/create/tasks)。

对应地,ScaffolderApi接口新增了可选的listTasks方法,调用时需传入必填参数filterByOwnership,用于按归属过滤任务。

后端/v2/tasks列表路由

@backstage/plugin-scaffolder-backend@1.3.0TaskBrokerTaskStore接口新增了可选的list方法(按可选的userEntityRef过滤),并在DatabaseTaskStore中实现了该方法。同时新增/v2/tasks路由,可通过createdBy查询参数按用户实体引用(userEntityRef)列出任务。当前仓库中该路由的实现位于 plugins/scaffolder-backend/src/service/router.ts,GET /v2/tasks会解析createdBy参数并透传给任务存储层进行过滤。同文件还提供了/v2/tasks/:taskIdcancelretryeventstream等任务生命周期管理端点。

表单字段访问:自定义字段读取其他表单数据

ScaffolderApi与字段扩展机制支持自定义字段组件通过props.formContext.formData读取表单中其他字段的值:

const CustomFieldExtensionComponent = (props: FieldExtensionComponentProps<string[]>) => { const { formData } = props.formContext; ... }; const CustomFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ name: ..., component: CustomFieldExtensionComponent, validation: ... }) );

这一能力让字段间的联动(如根据仓库类型动态调整可见选项)成为可能。

新的 Gerrit 集成与gerrit:publish动作

  • 前端新增针对 Gerrit 的RepoUrlPicker@backstage/plugin-scaffolder@1.3.0);
  • 后端新增gerrit:publishscaffolder 动作(@backstage/plugin-scaffolder-backend@1.3.0);
  • @backstage/integration@1.2.1同步修复了 Gerrit 集成中resolveUrl对绝对路径的处理。

publish:github协作者参数修复(破坏性行为变化)

publish:github动作修复了"无法添加用户为协作者"的缺陷,但代价是参数语义发生了变化:

  • 添加团队为协作者:使用team字段(username字段仍可用但已弃用,官方建议迁移到team);
  • 添加用户为协作者:使用user字段。
- id: publish name: Publish action: publish:github input: repoUrl: ... collaborators: - access: ... team: my_team - access: ... user: my_username

同时,publish:gitlab:merge-request动作的projectid输入参数被弃用——它已能从repoUrl中解码,不再需要单独传入;其projectid输出也被projectPath取代。另外该版本还新增了"不保护默认分支"的选项,并在仓库创建失败时给出更详尽的错误说明。

模板脱离default命名空间运行

Scaffolder 前端与后端均新增了对default命名空间模板的支持(@backstage/plugin-scaffolder@1.3.0@backstage/plugin-scaffolder-backend@1.3.0各自的f93af969cd变更),并修复了MultistepJsonForm的 review mask 行为(设置 mask 后不再需要额外的show: true),以及 dry-run 内容上传时对二进制文件与超大文件的处理。

搜索体验升级:结果rankdiscover分析事件

v1.3.0 围绕搜索体验做了一轮跨插件联动优化,核心是让搜索结果的可分析性更强:

  • @backstage/plugin-search-common@0.3.5Result类型上新增可选的rank属性,表示某结果在结果集中的排名(从 1 开始);
  • @backstage/plugin-search-backend@0.5.3以及-elasticsearch@0.1.5-pg@0.3.4提供的搜索引擎现在都会为所有结果附加分页感知(pagination-aware)的rank值;
  • @backstage/plugin-catalog@1.3.0@backstage/plugin-techdocs@1.2.0提供的<*ResultListItem />组件将点击分析事件从click升级为discover:事件以结果排名作为value属性,同时保留点击目标作为to属性。这一设计简化了搜索漏斗分析——discover事件语义上代表"发现",比"点击"更贴合搜索结果场景。

应用侧如需让自定义搜索组件参与分析,可在渲染结果项时透传rank。此外,@backstage/plugin-search@0.9.0移除了SearchPageNextSearchBarNext等 pre-alpha 组件,请改用@backstage/plugin-search-react@backstage/plugin-search中的非*Next等价组件;DefaultResultListItemSearchBar(含SearchBarBase)、SearchFilter(含.Checkbox/.Select/.Autocomplete)、SearchResultSearchResultPager等组件均已从@backstage/plugin-search迁移至@backstage/plugin-search-react导出,旧位置已弃用、未来将移除。

TechDocs 改进:并发构建限制与构建日志输出

@backstage/plugin-techdocs-backend@1.1.2带来两项运维向增强:

  1. 并发构建上限:当techdocs.builder配置为local时,并发构建数被限制为 10,超出部分将排队等待。若确有更高并发需求,官方建议横向扩容 TechDocs 后端部署,或改用external构建方式;
  2. 构建日志输出到日志传输层createRouter新增buildLogTransport参数,可将构建日志同时输出到后端日志流(而不只是前端事件流),便于在浏览器之外捕获构建失败原因。典型用法如下(完整示例见 plugins/techdocs-backend 相关代码):
import { DockerContainerRunner } from '@backstage/backend-common'; import { createRouter, Generators, Preparers, Publisher, } from '@backstage/plugin-techdocs-backend'; import Docker from 'dockerode'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise<Router> { const preparers = await Preparers.fromConfig(env.config, { logger: env.logger, reader: env.reader, }); const dockerClient = new Docker(); const containerRunner = new DockerContainerRunner({ dockerClient }); const generators = await Generators.fromConfig(env.config, { logger: env.logger, containerRunner, }); const publisher = await Publisher.fromConfig(env.config, { logger: env.logger, discovery: env.discovery, }); await publisher.getReadiness(); return await createRouter({ preparers, generators, publisher, logger: env.logger, // Passing a buildLogTransport as a parameter in createRouter will enable // capturing build logs to a backend log stream buildLogTransport: env.logger, config: env.config, discovery: env.discovery, cache: env.cache, }); }

同期前端@backstage/plugin-techdocs@1.2.0的改进包括:EntityTechdocsContent改用对象而非<Route>元素以修复子页面 outlet 为空导致 addon 不渲染的问题;读者页样式转换逻辑被重构为若干 hooks(sanitizeDOM等转换器改为 hook);addons 渲染过程修复了侧边栏闪烁与重复创建的问题;TechDocsReaderPageHeaderTechDocsSearch优先使用实体标题作为文案;并为 Catalog / TechDocs 搜索结果新增可选图标。

其他值得关注的新插件与能力

新插件首发

  • @backstage/plugin-dynatrace@0.1.0:Dynatrace 观测平台前端插件;
  • @backstage/plugin-vault@0.1.0@backstage/plugin-vault-backend@0.1.0:HashiCorp Vault 密钥管理的前后端插件(首次实现,详情见各插件 README);
  • @backstage/plugin-github-pull-requests-board@0.1.0:GitHub Pull Requests 看板插件。

Kubernetes 支持扩展

@backstage/plugin-kubernetes-backend@0.6.0@backstage/plugin-kubernetes-common@0.3.0新增对 StatefulSet 的数据拉取支持,前端@backstage/plugin-kubernetes@0.6.6以与 Deployments 相同的折叠面板方式展示 StatefulSet,并新增 CPU/内存 request/limit 展示、Kubernetes 页签刷新间隔可配置、多命名空间下 HPA 匹配修复、Azure token 缓存刷新等改进。

权限体系完善

@backstage/plugin-permission-node@0.6.2新增权限元数据聚合端点/.well-known/backstage/permissions/metadata,默认返回插件支持的权限规则信息;插件作者可通过createPermissionIntegrationRouter的可选permissions参数补充Permission对象(未来该参数将变为必填)。

Catalog 杂项

  • CatalogBuilder.addEntityProvider支持以数组形式一次传入多个 Provider,无需再逐个展开(builder.addEntityProvider(getArrayOfProviders()));
  • Catalog 后端禁止通过 location 服务注册除'url'类型以外的任何 location 类型;
  • plugin-catalog@1.3.0isKindisComponentTypeisNamespace过滤器支持传入值数组进行匹配;
  • plugin-org@0.5.6MyGroupsSidebarItem新增filter属性,可按spec.type等条件过滤所展示的组,例如filter={{ 'spec.type': 'team' }}
  • LDAP 模块新增 TLS 连接配置支持;plugin-catalog-backend-module-github@0.1.4为 GitHub Teams Group 实体补充了编辑 URL。

升级到 v1.3.0 的检查清单

综合上文,从 v1.2.0 升级到 v1.3.0 时建议逐项核对:

  1. Token 生命周期:检查所有getToken()调用点,确保每次按需获取,不缓存复用;为旧 token 的exp过期留出切换窗口;
  2. Git 平台发现迁移:若使用 Bitbucket Cloud / Azure DevOps / GitLab 的 discovery Processor,迁移到对应的 Entity Provider 并补充schedule配置(代码或配置二选一);
  3. Scaffolder:核对publish:github协作者字段(user/team),评估是否迁移publish:gitlab:merge-requestprojectid用法;
  4. 搜索组件导入:将SearchBarSearchFilterDefaultResultListItem等组件改从@backstage/plugin-search-react导入,删除*Next组件引用;
  5. TechDocs:如需构建日志,在createRouter中传入buildLogTransport;评估local构建模式下 10 并发上限是否满足需求;
  6. 权限端点:可选地在createPermissionIntegrationRouter中补充permissions参数,为元数据端点提供更丰富的信息。

本文所有代码示例均来自变更日志原文与仓库当前实现(如 plugins/catalog-backend-module-bitbucket-cloud 的 Provider 与配置解析源码、plugins/scaffolder-backend/src/service/router.ts 的/v2/tasks实现),可在对应路径继续深入研读。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询