Merge branch 'backstage:master' into home-visit-enrichment-transform-save

This commit is contained in:
sswane
2025-08-15 09:02:22 -05:00
committed by GitHub
465 changed files with 10223 additions and 12419 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-openapi-utils': patch
---
Update `express-openapi-validator` to 5.5.8 to fix security vulnerability in transitive dependency `multer`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Added missing space for alert display component
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-app': patch
---
Log a warning when `SwappableComponent` extensions are installed outside of using the `app` plugin
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-app': patch
---
Default implementations of core components are now provided by this package.
A backwards compatible `componentsApi` implementation is also provided from this package which uses the `SwappableComponentsApi` as the implementation. This backwards compatible wrapper will be removed in the future.
+15
View File
@@ -0,0 +1,15 @@
---
'@backstage/plugin-app': minor
---
**BREAKING**: The `componentsApi` implementation has been removed from the plugin and replaced with the new `SwappableComponentsApi` instead.
If you were overriding the `componentsApi` implementation, you can now use the new `SwappableComponentsApi` instead.
```ts
// old
appPlugin.getExtension('api:app/components').override(...)
// new
appPlugin.getExtension('api:app/swappable-components').override(...)
```
@@ -0,0 +1,96 @@
---
'@backstage/frontend-plugin-api': minor
---
**BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced:
- Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs`
- Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef`
**BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead.
- The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively.
- The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively.
- The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively.
**Migration for creating swappable components:**
```tsx
// OLD: Using createComponentRef and createComponentExtension
import {
createComponentRef,
createComponentExtension,
} from '@backstage/frontend-plugin-api';
const myComponentRef = createComponentRef<{ title: string }>({
id: 'my-plugin.my-component',
});
const myComponentExtension = createComponentExtension({
ref: myComponentRef,
loader: {
lazy: () => import('./MyComponent').then(m => m.MyComponent),
},
});
// NEW: Using createSwappableComponent and SwappableComponentBlueprint
import {
createSwappableComponent,
SwappableComponentBlueprint,
} from '@backstage/frontend-plugin-api';
const MySwappableComponent = createSwappableComponent({
id: 'my-plugin.my-component',
loader: () => import('./MyComponent').then(m => m.MyComponent),
});
const myComponentExtension = SwappableComponentBlueprint.make({
name: 'my-component',
params: {
component: MySwappableComponent,
loader: () => import('./MyComponent').then(m => m.MyComponent),
},
});
```
**Migration for using components:**
```tsx
// OLD: Using ComponentsApi and useComponentRef
import {
useComponentRef,
componentsApiRef,
useApi,
coreComponentRefs,
} from '@backstage/frontend-plugin-api';
const MyComponent = useComponentRef(myComponentRef);
const ProgressComponent = useComponentRef(coreComponentRefs.progress);
// NEW: Direct component usage
import { Progress } from '@backstage/frontend-plugin-api';
// Use directly as React Component
<Progress />
<MySwappableComponent title="Hello World" />
```
**Migration for core component references:**
```tsx
// OLD: Core component refs
import { coreComponentRefs } from '@backstage/frontend-plugin-api';
coreComponentRefs.progress
coreComponentRefs.notFoundErrorPage
coreComponentRefs.errorBoundaryFallback
// NEW: Direct swappable component imports
import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api';
// Use directly as React components
<Progress />
<NotFoundErrorPage />
<ErrorDisplay plugin={plugin} error={error} resetError={resetError} />
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': patch
---
Export CardHeader, CardBody and CardFooter from Card component index
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
---
Show additional information about the cause in error messages from GitLab
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': minor
---
We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': minor
---
**BREAKING**: The `ResolveInputValueOverrides` type is no longer exported.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-catalog-backend-module-gcp': patch
---
Added support for Google Service account credentials config used in GkeEntityProvider.
Added support for additional metadata `authProvider` and `owner` to be set for the GKE cluster entities.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-app-api': minor
---
Use an app plugin for built-in extension app node specs.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-compat-api': patch
---
The `compatWrapper` has been switched to use the new `SwappableComponentsApi` instead of the old `ComponentsApi` in its bridging to the old frontend system.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-kubernetes-backend': minor
---
**BREAKING CHANGE**: Removed support for the legacy backend system. This means that the deprecated `createRouter` and `KubernetesBuilder` and related types have been removed. Please refer to the [relevant documentation](https://backstage.io/docs/features/kubernetes/installation/#adding-kubernetes-backend-plugin) to configure the Kubernetes plugin.
**BREAKING CHANGE**: The deprecated types `AuthenticationStrategy`, `AuthMetadata`, `ClusterDetails`, `CustomResource`, `CustomResourcesByEntity`, `FetchResponseWrapper`, `KubernetesBuilder`, `KubernetesBuilderReturn`, `KubernetesClustersSupplier`, `KubernetesCredential`, `KubernetesEnvironment`, `KubernetesFetcher`, `KubernetesObjectsProvider`, `KubernetesObjectTypes`, `KubernetesServiceLocator`,`ObjectFetchParams`, `ObjectToFetch`,`RouterOptions` and `ServiceLocatorRequestContext` should all now be imported from `@backstage/plugin-kubernetes-node`.
+13
View File
@@ -0,0 +1,13 @@
---
'@backstage/backend-test-utils': patch
---
Updated the type definition of `mockErrorHandler` to ensure that it is used correctly.
```ts
// This is wrong and will now result in a type error
app.use(mockErrorHandler);
// This is the correct usage
app.use(mockErrorHandler());
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': patch
---
**Breaking change** Move breadcrumb to fit in the `HeaderPage` instead of the `Header` in Backstage UI.
+23
View File
@@ -0,0 +1,23 @@
---
'@backstage/cli': minor
---
**BREAKING**: The new app build based on [Rspack](https://rspack.dev/) is now the default, and the `EXPERIMENTAL_RSPACK` flag has been removed. To revert to the old behavior, set the `LEGACY_WEBPACK_BUILD` environment flag and install the following optional dependencies:
```json
{
"dependencies": {
"@module-federation/enhanced": "^0.9.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
"esbuild-loader": "^4.0.0",
"eslint-webpack-plugin": "^4.2.0",
"fork-ts-checker-webpack-plugin": "^9.0.0",
"mini-css-extract-plugin": "^2.4.2",
"terser-webpack-plugin": "^5.1.3",
"webpack": "^5.96.0",
"webpack-dev-server": "^5.0.0"
}
}
```
If you do encounter a blocking issue that forces you to use the old WebPack build, please [open an issue](https://github.com/backstage/backstage/issues) explaining the problem. The WebPack build will be removed in a future release.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-proxy-backend': patch
---
correct rewrite rule to avoid extra subpath in proxy path
+13
View File
@@ -0,0 +1,13 @@
---
'@backstage/plugin-catalog-backend': patch
---
Make the processing hash calculation not care about the order of the processors.
This change does not affect the behavior of the catalog, but it will make the processing
hash calculation more robust against changes in the order of processors. This should lead to
more stable processing hashes, which in turn should lead to fewer unnecessary reprocessing
of entities.
After deploying this fix, you may see a period of increased processing and stitching, but
this should stabilize over time as the processing hashes become more consistent.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Fixes CSS to adjust based on whether or not the global Backstage sidebar is on the page.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': minor
---
**BREAKING**: Removed support for `.icon.svg` imports, which have been deprecated since the 1.19 release.
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-catalog-graph': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-org': patch
---
Updated README instructions for the new frontend system
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': minor
---
Add resizable panels width for the editor and preview panels in the template editor and template form playground layouts. Users can now resize these panels by dragging the divider between the two areas.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': minor
---
Backstage UI - HeaderPage - We are updating the breadcrumb to be more visible and accessible.
+43
View File
@@ -207,6 +207,7 @@
"changesets": [
"afraid-poets-thank",
"blue-apples-pump",
"brave-pumas-attack",
"bright-elephants-sparkle",
"calm-geese-serve",
"chatty-coats-sin",
@@ -216,66 +217,108 @@
"clean-chairs-sit",
"clever-plants-warn",
"cold-heads-arrive",
"cold-lemons-design",
"common-heads-build",
"component-refs-app",
"component-refs-breaking-app",
"component-refs-breaking-frontend-plugin-api",
"crazy-pants-exist",
"create-app-1753196727",
"create-app-1754401469",
"cruel-bars-buy",
"cruel-zoos-argue",
"deep-apples-attack",
"deep-mangos-dig",
"eight-sloths-walk",
"eleven-tigers-drop",
"empty-years-grow",
"every-schools-find",
"evil-forks-hang",
"evil-phones-unite",
"fancy-ducks-help",
"fast-jars-push",
"fifty-ads-dance",
"five-ducks-hide",
"floppy-groups-hug",
"fluffy-otters-cry",
"four-spiders-jump",
"free-months-share",
"fruity-rockets-rhyme",
"full-streets-take",
"funny-brooms-trade",
"funny-dancers-start",
"fuzzy-ducks-jump",
"fuzzy-ducks-speak",
"gentle-cars-arrive",
"great-hounds-fix",
"great-snakes-dress",
"green-lies-invite copy",
"green-lies-invite",
"honest-moons-rest",
"honest-seas-repeat",
"honest-snakes-draw",
"hot-clowns-behave",
"huge-heads-occur",
"huge-paws-design",
"itchy-doodles-boil",
"late-squids-feel",
"lemon-ways-lay",
"little-bugs-care",
"long-grapes-glow",
"lovely-fans-write",
"major-comics-stay",
"mighty-cycles-stay",
"mira-looking-ostrich",
"moody-clowns-hear",
"nej-inte-ostrich",
"nice-actors-cheer",
"nice-buttons-return",
"nice-crabs-clean",
"odd-beans-sell",
"olive-baths-punch",
"open-bottles-film",
"open-seas-ring",
"orange-teams-smell",
"petite-spoons-flash",
"polite-trains-notice",
"quick-keys-post",
"quiet-parks-cheer",
"renovate-49770ce",
"renovate-c6c2a22",
"rich-seals-itch",
"ripe-comics-sip",
"rotten-rats-dream",
"sad-candies-open",
"sad-cities-lay",
"seven-crabs-stick",
"shaggy-parrots-deny",
"shiny-rats-accept",
"short-parks-love",
"silent-bats-jam",
"sixty-clowns-float",
"slick-cameras-bet",
"small-trams-do",
"smart-planes-march",
"solid-ducks-flow",
"spotty-clowns-lose",
"spotty-icons-shake",
"strong-dogs-raise",
"tame-sloths-boil",
"tangy-pets-smoke",
"tender-crabs-stay",
"tender-olives-clean",
"thick-breads-add",
"thick-hotels-enter",
"thirty-dingos-allow",
"thirty-eagles-run",
"thirty-jobs-cut",
"three-mammals-move",
"three-snakes-deny",
"tired-lamps-start",
"twenty-pumas-brush",
"violet-weeks-trade",
"wet-ghosts-rhyme",
"whole-glasses-visit",
"whole-hands-cut",
"wild-apes-care",
"yellow-ducks-burn"
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': patch
---
Remove stylesheet import from Select component.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-github': patch
---
Fixed bug in the `customProperties` type which was preventing it being used to set a list of values against a key (e.g. for multi-select fields)
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-events-backend-module-kafka': patch
---
Remove luxon dependency and minor internal improvements
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Fixed getLocationByEntity to use `original_value` instead of `value` when querying search table
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/ui': patch
---
Add `startCollapsed` prop on the `SearchField` component in BUI.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes': patch
---
Removed the kubernetes content padding to avoid double padding on k8s entity page
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/frontend-defaults': patch
'@backstage/frontend-app-api': patch
'@backstage/cli': patch
---
Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-backend': patch
---
Added support for Google Service account credentials config to use in GoogleServiceAccountStrategy
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-app-api': patch
---
Added a default implementation of the `SwappableComponentsApi` and removing the legacy `ComponentsApi` implementation
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/create-app': patch
---
Updated the `app.packages` config setting now that it no longer is experimental
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-defaults': patch
---
**BREAKING**: The `loadingComponent` option has been renamed to `loadingElement`, which is now found under `advanced.loadingElement`. The default loading element has also been switched to `<Progress />` from `@backstage/core-components`. This is of course an improvement over the previous `"Loading..."` text, but also helps prevent flicker when the app loading is fast.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-github': patch
---
Fix GitHub catalog entity provider branch matching on event processing.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-app-api': minor
---
The `AppNodeSpec.plugin` property is now required.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
add `getResources` method to `permissionIntegrationRouter` for frontend task permission checks
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Implement max length for scaffolder auditor audit logging with default of 256
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-gitlab-org': patch
---
feat: Add gitlabOrgEntityProviderTransformsExtensionPoint for overriding user and group transformers
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
The Node.js transform in `@backstage/cli/config/nodeTransformHooks.mjs` now supports the built-in type stripping in Node.js, which is enabled by default from v22.18.0.
+23
View File
@@ -0,0 +1,23 @@
---
'@backstage/frontend-defaults': minor
'@backstage/frontend-app-api': minor
---
**BREAKING**: Restructured some of option fields of `createApp` and `createSpecializedApp`.
- For `createApp`, all option fields _except_ `features` and `bindRoutes` have been moved into a new `advanced` object field.
- For `createSpecializedApp`, all option fields _except_ `features`, `config`, and `bindRoutes` have been moved into a new `advanced` object field.
This helps highlight that some options are meant to rarely be needed or used, and simplifies the usage of those options that are almost always required.
As an example, if you used to supply a custom config loader, you would update your code as follows:
```diff
createApp({
features: [...],
- configLoader: new MyCustomLoader(),
+ advanced: {
+ configLoader: new MyCustomLoader(),
+ },
})
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': patch
---
Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`.
-5
View File
@@ -30,11 +30,6 @@
rangeStrategy: 'replace',
matchSourceUrls: ['https://github.com/microsoft/rushstack{/,}**'],
},
{
groupName: 'SVGR monorepo packages',
rangeStrategy: 'replace',
matchSourceUrls: ['https://github.com/gregberge/svgr{/,}**'],
},
{
groupName: 'Module-federation monorepo packages',
rangeStrategy: 'replace',
@@ -467,6 +467,7 @@ Superfences
superset
supertype
SVGs
swappable
talkdesk
Talkdesk
Tanzu
@@ -551,3 +552,4 @@ zod
Zolotusky
zoomable
zsh
resizable
@@ -23,7 +23,7 @@ jobs:
comment-cache-key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
disable-sudo: true
egress-policy: block
@@ -74,7 +74,7 @@ jobs:
- name: Cache Comment
if: ${{ steps.event.outputs.ACTION != 'closed' }}
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: comment.md
key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
name: Test ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
name: Install ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -64,7 +64,7 @@ jobs:
name: Verify ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -52,7 +52,7 @@ jobs:
working-directory: ./example-app
- name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with:
registry: ghcr.io
username: ${{ github.actor }}
+6 -12
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -135,7 +135,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -192,20 +192,14 @@ jobs:
path: .cache/package-docs
key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-${{ github.run_id }}
# Also build and upload storybook
- name: storybook yarn install
run: yarn install --immutable
working-directory: storybook
- name: storybook build
- name: Build Storybook
run: yarn build-storybook
working-directory: storybook
- name: storybook upload
- name: Upload Storybook
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: storybook
path: storybook/dist/
path: dist-storybook
if-no-files-found: error
retention-days: 1
@@ -246,7 +240,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -151,7 +151,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
if: github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
steps:
# Inspired by https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request )
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -11,7 +11,7 @@ jobs:
if: github.actor == 'dependabot[bot]' && github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -11,7 +11,7 @@ jobs:
if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage'
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
name: E2E Linux ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -43,7 +43,7 @@ jobs:
name: E2E Linux ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
name: Techdocs
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -25,7 +25,7 @@ jobs:
name: E2E Windows ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
name: E2E Windows ${{ matrix.node-version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
name: Microsite
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+6 -12
View File
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -137,7 +137,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -192,20 +192,14 @@ jobs:
path: .cache/package-docs
key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-next-${{ github.run_id }}
# Also build and upload storybook
- name: storybook yarn install
run: yarn install --immutable
working-directory: storybook
- name: storybook build
- name: Build Storybook
run: yarn build-storybook
working-directory: storybook
- name: storybook upload
- name: Upload Storybook
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: storybook
path: storybook/dist/
path: dist-storybook
if-no-files-found: error
retention-days: 1
@@ -240,7 +234,7 @@ jobs:
name: Microsite
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -24,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
name: Storybook
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+13 -15
View File
@@ -4,7 +4,8 @@ on:
pull_request:
paths:
- '.github/workflows/verify_storybook.yml'
- 'storybook/**'
- '.storybook/**'
- 'packages/ui/src/**'
- 'packages/config/src/**'
- 'packages/theme/src/**'
- 'packages/types/src/**'
@@ -28,37 +29,34 @@ jobs:
name: Storybook
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Required to retrieve git history
- name: use node.js ${{ matrix.node-version }}
- name: Use node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/ # Needed for auth
- name: yarn install
- name: Install dependencies
uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
- name: storybook yarn install
run: yarn install --immutable
working-directory: storybook
# Only for verification, the BUI one is what we upload to Chromatic
- run: yarn build-storybook
- name: Build Storybook
run: yarn build-storybook
- run: yarn --cwd packages/ui build-storybook
- uses: chromaui/action@1cfa065cbdab28f6ca3afaeb3d761383076a35aa # v11
- name: Deploy Storybook to Chromatic
uses: chromaui/action@1cfa065cbdab28f6ca3afaeb3d761383076a35aa # v11
with:
token: ${{ secrets.GITHUB_TOKEN }}
# projectToken intentionally shared to allow collaborators to run Chromatic on forks
# https://www.chromatic.com/docs/custom-ci-provider#run-chromatic-on-external-forks-of-open-source-projects
projectToken: chpt_dab72dc0f97d55b
workingDir: packages/ui
storybookBuildDir: storybook-static
storybookBuildDir: dist-storybook
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
+3
View File
@@ -184,3 +184,6 @@ knip.json
type-docs
docs.json
tsconfig.typedoc.tmp.json
# Storybook
dist-storybook/
@@ -2,10 +2,9 @@ import type { StorybookConfig } from '@storybook/react-vite';
import { join, dirname, posix } from 'path';
/**
* This set of stories are the ones that we publish to backstage.io.
*/
// This set of stories are the ones that we publish to backstage.io.
const backstageCoreStories = [
'packages/ui',
'packages/core-components',
'packages/app',
'plugins/org',
@@ -15,7 +14,7 @@ const backstageCoreStories = [
'plugins/catalog-react',
];
const rootPath = '../../';
const rootPath = '../';
const storiesSrcMdx = 'src/**/*.mdx';
const storiesSrcGlob = 'src/**/*.stories.@(js|jsx|mjs|ts|tsx)';
@@ -27,10 +26,7 @@ const stories = backstageCoreStories.flatMap(element => [
getStoriesPath(element, storiesSrcGlob),
]);
/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
// Resolve absolute path of a package. Needed in monorepos.
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, 'package.json')));
}
@@ -40,7 +36,6 @@ const config: StorybookConfig = {
addons: [
getAbsolutePath('@storybook/addon-links'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-interactions'),
getAbsolutePath('@storybook/addon-themes'),
getAbsolutePath('@storybook/addon-storysource'),
@@ -50,4 +45,5 @@ const config: StorybookConfig = {
options: {},
},
};
export default config;
+126
View File
@@ -0,0 +1,126 @@
import React, { useEffect } from 'react';
import { TestApiProvider } from '@backstage/test-utils';
import { Content, AlertDisplay } from '@backstage/core-components';
import { apis } from './support/apis';
import type { Decorator, Preview } from '@storybook/react';
import { useGlobals } from '@storybook/preview-api';
import { UnifiedThemeProvider, themes } from '@backstage/theme';
// Default Backstage theme CSS (from packages/ui)
import '../packages/ui/src/css/styles.css';
// Custom Storybook chrome/styles
import './storybook.css';
// Custom themes
import './themes/spotify.css';
const preview: Preview = {
globalTypes: {
themeMode: {
name: 'Theme Mode',
description: 'Global theme mode for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', icon: 'circlehollow', title: 'Light' },
{ value: 'dark', icon: 'circle', title: 'Dark' },
],
showName: true,
dynamicTitle: true,
},
},
themeName: {
name: 'Theme Name',
description: 'Global theme name for components',
defaultValue: 'backstage',
toolbar: {
icon: 'paintbrush',
items: [
{ value: 'backstage', title: 'Backstage' },
{ value: 'spotify', title: 'Spotify' },
],
showName: true,
dynamicTitle: true,
},
},
},
initialGlobals: {
themeMode: 'light',
themeName: 'backstage',
},
parameters: {
layout: 'fullscreen',
backgrounds: {
disable: true,
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
options: {
storySort: {
order: ['Backstage UI', 'Plugins', 'Layout', 'Navigation'],
},
},
viewport: {
viewports: {
initial: {
name: 'Initial',
styles: { width: '320px', height: '100%' },
},
xs: { name: 'Extra Small', styles: { width: '640px', height: '100%' } },
sm: { name: 'Small', styles: { width: '768px', height: '100%' } },
md: { name: 'Medium', styles: { width: '1024px', height: '100%' } },
lg: { name: 'Large', styles: { width: '1280px', height: '100%' } },
xl: {
name: 'Extra Large',
styles: { width: '1536px', height: '100%' },
},
},
},
},
decorators: [
Story => {
const [globals] = useGlobals();
const selectedTheme =
globals.themeMode === 'light' ? themes.light : themes.dark;
const selectedThemeMode = globals.themeMode || 'light';
const selectedThemeName = globals.themeName || 'backstage';
useEffect(() => {
document.body.removeAttribute('data-theme-mode');
document.body.removeAttribute('data-theme-name');
document.body.setAttribute('data-theme-mode', selectedThemeMode);
document.body.setAttribute('data-theme-name', selectedThemeName);
return () => {
document.body.removeAttribute('data-theme-mode');
document.body.removeAttribute('data-theme-name');
};
}, [selectedTheme, selectedThemeName]);
document.body.style.backgroundColor = 'var(--bui-bg)';
const docsStoryElements = document.getElementsByClassName('docs-story');
Array.from(docsStoryElements).forEach(element => {
(element as HTMLElement).style.backgroundColor = 'var(--bui-bg)';
});
return (
<UnifiedThemeProvider theme={selectedTheme}>
{/* @ts-ignore */}
<TestApiProvider apis={apis}>
<AlertDisplay />
<Content>
<Story />
</Content>
</TestApiProvider>
</UnifiedThemeProvider>
);
},
],
};
export default preview;
@@ -12,7 +12,7 @@
--sb-content-padding-inline: 250px;
}
[data-theme='dark'] {
[data-theme-mode='dark'] {
--sb-sidebar-bg: var(--bui-bg-surface-1);
}
@@ -30,7 +30,7 @@
--sb-content-padding-inline: 258px;
}
[data-theme-name='spotify'][data-theme='light'] {
[data-theme-name='spotify'][data-theme-mode='light'] {
--sb-sidebar-border: 1px solid var(--bui-border);
--sb-sidebar-border-right: 1px solid var(--bui-border);
--sb-options-border: 1px solid var(--bui-border);
@@ -205,9 +205,13 @@
padding-inline: var(--bui-space-1);
border: none;
}
.bui-Input {
border-radius: var(--bui-radius-3);
}
}
[data-theme='light'][data-theme-name='spotify'] {
[data-theme-mode='light'][data-theme-name='spotify'] {
--bui-bg: var(--bui-gray-1);
--bui-bg-surface-1: var(--bui-white);
--bui-bg-surface-2: var(--bui-gray-2);
@@ -239,7 +243,7 @@
}
}
[data-theme='dark'][data-theme-name='spotify'] {
[data-theme-mode='dark'][data-theme-name='spotify'] {
--bui-bg: var(--bui-black);
--bui-bg-surface-1: var(--bui-gray-1);
--bui-bg-surface-2: var(--bui-gray-2);
+3 -2
View File
@@ -1,8 +1,7 @@
app:
title: Backstage Example App
baseUrl: http://localhost:3000
experimental:
packages: all # ✨
packages: all # ✨
#datadogRum:
# clientToken: '123456789'
@@ -200,6 +199,8 @@ catalog:
- allow: [Template]
scaffolder:
auditor:
taskParameterMaxLength: 256
# Use to customize default commit author info used when new components are created
defaultAuthor:
name: Scaffolder
+46 -30
View File
@@ -1,6 +1,6 @@
---
title: Backstage Notifications System
status: implementable
status: implemented
authors:
- '@Rugvip'
- '@drodil'
@@ -105,7 +105,6 @@ The notification backend stores notification using the [database service](https:
- Description (optional)
- Origin
- Link (optional)
- Additional links (optional)
- Severity (optional, default normal)
- Topic (optional)
- Scope (optional)
@@ -193,8 +192,6 @@ The following backend service interfaces are added as part of this proposal.
#### `NotificationService`
```ts
// TODO - We may want to add an additional wrapping here with interfaces for Notification and NotificationParameters
export type NotificationRecipients =
| {
type: 'entity';
@@ -210,7 +207,6 @@ export type NotificationPayload = {
title: string;
description?: string;
link?: string;
additionalLinks?: string[];
severity?: NotificationSeverity;
topic?: string;
scope?: string;
@@ -233,20 +229,20 @@ export type Notification = {
payload: NotificationPayload;
};
interface SendNotificationRequest {
interface NotificationSendOptions {
recipients: NotificationRecipients;
payload: NotificationPayload;
}
interface NotificationService {
sendNotification(request: SendNotificationRequest): Promise<void>;
send(request: NotificationSendOptions): Promise<void>;
}
```
Each notification contains a human-readable `title`, `origin` and optionally `link` for additional details. The `created`, `id`, `read` and `saved` properties are handled by the backend based and cannot be passed during the notification creation.
Any optional additional details could be stored in `metadata`. We advise to provide the name to the type which contains the information about the context and the version, for example: 'core.icon.v1'.
Calling `sendNotification` should never throw an error so that it doesn't block the current processing. Notifications should be considered as second-level citizens that are not critical if not delivered.
Calling `send` should never throw an error so that it doesn't block the current processing. Notifications should be considered as second-level citizens that are not critical if not delivered.
Each notification is always routed to individual users unless its type is `broadcast`.
@@ -300,8 +296,6 @@ Example signal payload for a new notification:
- OpenAPI tooling is taken into use for the notification router and client
- Allow using dynamic values in notification payload, for example entity references `{{ user:default/john.doe }}` should be rendered by the frontend with `EntityRefLink` component. Defining the dynamic data values should be done before implementation.
- Add configurable automatic clean-up of old notifications to save storage space
- Support for saving user notification settings
### Frontend API
@@ -309,7 +303,7 @@ Notification frontend shows users their own notifications in its own page and th
Notifications are set to `read` when the `Mark as read` action is triggered by the user (bulk or single).
Notifications can be saved for better visibility in the future.
Notifications can be saved for better visibility.
Notifications can be filtered by `read`, `saved`, `content` (text search in title or description), `created` (since multiple predefined options) and `severity`.
@@ -322,42 +316,64 @@ The following frontend API is added as part of this proposal.
```ts
export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low';
export type GetNotificationsOptions = {
offset?: number;
limit?: number;
export type GetNotificationsCommonOptions = {
search?: string;
createdSince?: Date;
severity?: NotificationSeverity;
read?: boolean;
saved?: boolean;
createdAfter?: Date;
minimumSeverity?: NotificationSeverity;
};
export type NotificationUpdateOptions = {
export type GetNotificationsOptions = GetNotificationsCommonOptions & {
offset?: number;
limit?: number;
sort?: 'created' | 'topic' | 'origin';
sortOrder?: 'asc' | 'desc';
topic?: string;
};
export type GetTopicsOptions = GetNotificationsCommonOptions;
export type UpdateNotificationsOptions = {
ids: string[];
read?: boolean;
saved?: boolean;
};
export type NotificationStatus = {
unread: number;
read: number;
export type GetNotificationsResponse = {
notifications: Notification[];
totalCount: number;
};
interface NotificationsApi {
getNotifications(options?: GetNotificationsOptions): Promise<Notification[]>;
export type GetTopicsResponse = {
topics: string[];
};
export interface NotificationsApi {
getNotifications(
options?: GetNotificationsOptions,
): Promise<GetNotificationsResponse>;
getNotification(id: string): Promise<Notification>;
getStatus(): Promise<NotificationStatus>;
updateNotifications(
options: UpdateNotificationsOptions,
): Promise<Notification[]>;
getNotificationSettings(): Promise<NotificationSettings>;
updateNotificationSettings(
settings: NotificationSettings,
): Promise<NotificationSettings>;
getTopics(options?: GetTopicsOptions): Promise<GetTopicsResponse>;
}
```
#### `SignalApi`
> TODO - we likely need a slightly different approach here, since APIs are lazy loaded.
> TODO - signal typing in https://github.com/backstage/backstage/pull/22656
```ts
export type NotificationSignal = {
action: string;
@@ -427,14 +443,14 @@ The notification and signal plugins are released as two new plugins in the Backs
For the notification plugin to reach a stable release we much reach the following:
- [ ] A stable notifications payload format.
- [ ] A stable notifications recipient filter format.
- [x] A stable notifications payload format.
- [x] A stable notifications recipient filter format.
- [x] The events service must have at least one implementation that supports scaled deployments. Done in #24916.
For the signal plugin to reach a stable release we much reach the following:
- [ ] A stable signal recipient filter format.
- [ ] A stable signal channel API in the frontend.
- [x] A stable signal recipient filter format.
- [x] A stable signal channel API in the frontend.
If any changes are required to the frontend framework to facilitate the implementation of notifications or signals, these will be released as experimental alpha features. They will stay in alpha until they are deemed stable enough, which must happen before a stable release of the notifications system.
+2 -2
View File
@@ -23,7 +23,7 @@
"@mdx-js/react": "^3.1.0",
"@next/mdx": "15.3.4",
"@remixicon/react": "^4.6.0",
"@storybook/react": "^8.6.8",
"@storybook/react": "^8.6.12",
"@uiw/codemirror-themes": "^4.23.7",
"@uiw/react-codemirror": "^4.23.7",
"html-react-parser": "^5.2.5",
@@ -34,7 +34,7 @@
"react": "19.1.1",
"react-dom": "19.1.1",
"shiki": "^1.26.1",
"storybook": "^8.6.8"
"storybook": "^8.6.12"
},
"devDependencies": {
"@types/mdx": "^2.0.13",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -14,7 +14,7 @@ const config = {
name: 'Main Styles',
},
{
source: '.storybook/themes/spotify.css',
source: '../../.storybook/themes/spotify.css',
destination: 'theme-spotify.css',
name: 'Spotify Theme',
},

Some files were not shown because too many files have changed in this diff Show More