diff --git a/.changeset/loose-bees-see.md b/.changeset/loose-bees-see.md new file mode 100644 index 0000000000..35fd134816 --- /dev/null +++ b/.changeset/loose-bees-see.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added Notifications and Signals to be installed by default diff --git a/.changeset/twelve-ants-knock.md b/.changeset/twelve-ants-knock.md new file mode 100644 index 0000000000..434a2b4059 --- /dev/null +++ b/.changeset/twelve-ants-knock.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Stop logging of `SPLAT` twice in logs diff --git a/.changeset/wise-mails-agree.md b/.changeset/wise-mails-agree.md new file mode 100644 index 0000000000..1ad08c2ef6 --- /dev/null +++ b/.changeset/wise-mails-agree.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications-common': minor +--- + +Add an optional generic object `metadata` field to `NotificationPayload`. Metadata can be used to store additional unstructured data for the notification and are available to use by processors. diff --git a/beps/0001-notifications-system/README.md b/beps/0001-notifications-system/README.md index 03fb224e1c..bfea3115f9 100644 --- a/beps/0001-notifications-system/README.md +++ b/beps/0001-notifications-system/README.md @@ -211,10 +211,7 @@ export type NotificationPayload = { topic?: string; scope?: string; icon?: string; - metadata?: Array<{ - type: string; - value: JsonValue; - }>; + metadata?: { [KMetadataKey in string]?: JsonValue }; }; export type Notification = { diff --git a/docs/notifications/index.md b/docs/notifications/index.md index c31d2716e4..59ff2962ed 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -33,6 +33,12 @@ Example of use-cases: ## Installation +:::note + +As of the `1.42.0` release of Backstage, Notifications and Signals are installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. The only exception to this is adding the [Notifications tab to User Settings](#user-specific-notification-settings) to allow managing these settings. + +::: + The following sections will walk you through the installation of the various parts of the Backstage Notification System. ### Add Notifications Backend @@ -173,6 +179,52 @@ notifications: If the retention is set to false, notifications will not be automatically deleted. +## Scaffolder Action + +:::note + +As of the `1.42.0` release of Backstage, the Notifications Scaffolder action is installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. Feel free to skip to the [Basic Example](#basic-example). + +::: + +There is also a Scaffolder action that you can use to send a notification as part of your Software Template. + +First we need to add the backend package: + +```bash title="From your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-notifications +``` + +Then we need to add it to our backend: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); +// ... +backend.add( + import('@backstage/plugin-scaffolder-backend-module-notifications'), +); +``` + +### Basic Example + +Here's an example of how you can use it in your Software Template, more details and examples can be found in the "Installed actions" screen in your Backstage instances: + +```yaml title="template.yaml" +steps: + - id: notify + name: Notify + action: notification:send + input: + recipients: entity + entityRefs: + - user:default/guest + title: 'Template executed' + info: 'Your template has been executed' + severity: 'normal' +``` + +The example above would send a notification to the Guest user (`user:default/guest`) + ## Additional info An example of a backend plugin sending notifications can be found in the [`@backstage/plugin-scaffolder-backend-module-notifications` package](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-notifications). diff --git a/docs/notifications/usage.md b/docs/notifications/usage.md index 358426dc21..94de585d21 100644 --- a/docs/notifications/usage.md +++ b/docs/notifications/usage.md @@ -210,3 +210,68 @@ notificationsApi.getNotification(yourId); // or with connection to signals: notificationsApi.getNotification(lastSignal.notification_id); ``` + +## Metadata Field + +The metadata field is a freeform object that is designed to be used by processors. + +### Well-known Notification Metadata Fields + +Below are metadata fields that will be commonly used between processors and have defined schematics. + +#### backstage.io/body.markdown + +```ts +# Example: +const payload = { + title: 'Entities Require Attention', + description: 'Entities: Service A, Service B' + metadata: { + 'backstage.io/body.markdown': ` + # Entities + - Service A + - System B + ` + } +} +``` + +This value of this metadata field should be the notification message in markdown format. This allows additional formatting options for processors that support markdown. + +### Usage + +Below is an example of using the `backstage.io/body.markdown` metadata field in a custom processor. + +When sending a notification: + +```ts +notificationService.send({ + recipients: { type: 'entity', entityRef: 'group/default:team-a' }, + payload: { + title: 'Notification', + description: 'Description' + metadata: { + 'backstage.io/body.markdown': ` + ### Notification + Description + `, + }, + }, +}); +``` + +In the processor, you can then use the metadata field accordingly: + +```ts +async postProcess(notification: Notification): Promise { + // We suggest you parse the metadata field with a schema, i.e. Zod + const parseResult = CustomProcessorMetadataSchema.safeParse(notification.payload.metadata ?? {}); + const metadata = parseResult.success ? parseResult.data : {}; + + customNotificationSender.send({ + to: getUsers(notification.recipients), + subject: notification.payload.title, + markdownText: metadata['backstage.io/body.markdown'] ?? notification.payload.description, + }); +} +``` diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index c5d5092410..86a7008b4d 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -89,12 +89,17 @@ jest.mock('./versions', () => ({ '@backstage/plugin-catalog-react': '1.0.0', '@backstage/plugin-kubernetes': '1.0.0', '@backstage/plugin-kubernetes-backend': '1.0.0', + '@backstage/plugin-notifications': '1.0.0', + '@backstage/plugin-notifications-backend': '1.0.0', '@backstage/plugin-org': '1.0.0', '@backstage/plugin-scaffolder': '1.0.0', '@backstage/plugin-scaffolder-backend-module-github': '1.0.0', + '@backstage/plugin-scaffolder-backend-module-notifications': '1.0.0', '@backstage/plugin-permission-react': '1.0.0', '@backstage/plugin-search': '1.0.0', '@backstage/plugin-search-react': '1.0.0', + '@backstage/plugin-signals': '1.0.0', + '@backstage/plugin-signals-backend': '1.0.0', '@backstage/plugin-techdocs': '1.0.0', '@backstage/plugin-techdocs-react': '1.0.0', '@backstage/plugin-techdocs-module-addons-contrib': '1.0.0', diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index bd0ea7eb41..6785fb9b52 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -68,6 +68,8 @@ import { version as pluginCatalogGraph } from '../../../../plugins/catalog-graph import { version as pluginCatalogImport } from '../../../../plugins/catalog-import/package.json'; import { version as pluginKubernetes } from '../../../../plugins/kubernetes/package.json'; import { version as pluginKubernetesBackend } from '../../../../plugins/kubernetes-backend/package.json'; +import { version as pluginNotifications } from '../../../../plugins/notifications/package.json'; +import { version as pluginNotificationsBackend } from '../../../../plugins/notifications-backend/package.json'; import { version as pluginOrg } from '../../../../plugins/org/package.json'; import { version as pluginPermissionBackend } from '../../../../plugins/permission-backend/package.json'; import { version as pluginPermissionBackendModulePolicyAllowAll } from '../../../../plugins/permission-backend-module-policy-allow-all/package.json'; @@ -78,6 +80,7 @@ import { version as pluginProxyBackend } from '../../../../plugins/proxy-backend import { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json'; import { version as pluginScaffolderBackend } from '../../../../plugins/scaffolder-backend/package.json'; import { version as pluginScaffolderBackendModuleGithub } from '../../../../plugins/scaffolder-backend-module-github/package.json'; +import { version as pluginScaffolderBackendModuleNotifications } from '../../../../plugins/scaffolder-backend-module-notifications/package.json'; import { version as pluginSearch } from '../../../../plugins/search/package.json'; import { version as pluginSearchReact } from '../../../../plugins/search-react/package.json'; import { version as pluginSearchBackend } from '../../../../plugins/search-backend/package.json'; @@ -85,6 +88,8 @@ import { version as pluginSearchBackendModuleCatalog } from '../../../../plugins import { version as pluginSearchBackendModulePg } from '../../../../plugins/search-backend-module-pg/package.json'; import { version as pluginSearchBackendModuleTechdocs } from '../../../../plugins/search-backend-module-techdocs/package.json'; import { version as pluginSearchBackendNode } from '../../../../plugins/search-backend-node/package.json'; +import { version as pluginSignals } from '../../../../plugins/signals/package.json'; +import { version as pluginSignalsBackend } from '../../../../plugins/signals-backend/package.json'; import { version as pluginTechdocs } from '../../../../plugins/techdocs/package.json'; import { version as pluginTechdocsReact } from '../../../../plugins/techdocs-react/package.json'; import { version as pluginTechdocsModuleAddonsContrib } from '../../../../plugins/techdocs-module-addons-contrib/package.json'; @@ -130,6 +135,8 @@ export const packageVersions = { '@backstage/plugin-catalog-import': pluginCatalogImport, '@backstage/plugin-kubernetes': pluginKubernetes, '@backstage/plugin-kubernetes-backend': pluginKubernetesBackend, + '@backstage/plugin-notifications': pluginNotifications, + '@backstage/plugin-notifications-backend': pluginNotificationsBackend, '@backstage/plugin-org': pluginOrg, '@backstage/plugin-permission-backend': pluginPermissionBackend, '@backstage/plugin-permission-backend-module-allow-all-policy': @@ -142,6 +149,8 @@ export const packageVersions = { '@backstage/plugin-scaffolder-backend': pluginScaffolderBackend, '@backstage/plugin-scaffolder-backend-module-github': pluginScaffolderBackendModuleGithub, + '@backstage/plugin-scaffolder-backend-module-notifications': + pluginScaffolderBackendModuleNotifications, '@backstage/plugin-search': pluginSearch, '@backstage/plugin-search-react': pluginSearchReact, '@backstage/plugin-search-backend': pluginSearchBackend, @@ -151,6 +160,8 @@ export const packageVersions = { '@backstage/plugin-search-backend-module-techdocs': pluginSearchBackendModuleTechdocs, '@backstage/plugin-search-backend-node': pluginSearchBackendNode, + '@backstage/plugin-signals': pluginSignals, + '@backstage/plugin-signals-backend': pluginSignalsBackend, '@backstage/plugin-techdocs': pluginTechdocs, '@backstage/plugin-techdocs-react': pluginTechdocsReact, '@backstage/plugin-techdocs-module-addons-contrib': diff --git a/packages/create-app/templates/default-app/examples/template/template.yaml b/packages/create-app/templates/default-app/examples/template/template.yaml index f04c3241c5..efb33be866 100644 --- a/packages/create-app/templates/default-app/examples/template/template.yaml +++ b/packages/create-app/templates/default-app/examples/template/template.yaml @@ -66,6 +66,18 @@ spec: repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }} catalogInfoPath: '/catalog-info.yaml' + # Let's notify the user that the template has completed using the Notification action + - id: notify + name: Notify + action: notification:send + input: + recipients: entity + entityRefs: + - user:default/guest + title: 'Template executed' + info: 'Your template has been executed' + severity: 'normal' + # Outputs are displayed to the user after a successful execution of the template. output: links: diff --git a/packages/create-app/templates/default-app/packages/app/package.json.hbs b/packages/create-app/templates/default-app/packages/app/package.json.hbs index b7d16f8a84..5152113098 100644 --- a/packages/create-app/templates/default-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/app/package.json.hbs @@ -28,11 +28,13 @@ "@backstage/plugin-catalog-import": "^{{version '@backstage/plugin-catalog-import'}}", "@backstage/plugin-catalog-react": "^{{version '@backstage/plugin-catalog-react'}}", "@backstage/plugin-kubernetes": "^{{version '@backstage/plugin-kubernetes'}}", + "@backstage/plugin-notifications": "^{{ version '@backstage/plugin-notifications'}}", "@backstage/plugin-org": "^{{version '@backstage/plugin-org'}}", "@backstage/plugin-permission-react": "^{{version '@backstage/plugin-permission-react'}}", "@backstage/plugin-scaffolder": "^{{version '@backstage/plugin-scaffolder'}}", "@backstage/plugin-search": "^{{version '@backstage/plugin-search'}}", "@backstage/plugin-search-react": "^{{version '@backstage/plugin-search-react'}}", + "@backstage/plugin-signals": "^{{ version '@backstage/plugin-signals'}}", "@backstage/plugin-techdocs": "^{{version '@backstage/plugin-techdocs'}}", "@backstage/plugin-techdocs-module-addons-contrib": "^{{version '@backstage/plugin-techdocs-module-addons-contrib'}}", "@backstage/plugin-techdocs-react": "^{{version '@backstage/plugin-techdocs-react'}}", diff --git a/packages/create-app/templates/default-app/packages/app/src/App.tsx b/packages/create-app/templates/default-app/packages/app/src/App.tsx index 89b199c8d3..bb9c98eff8 100644 --- a/packages/create-app/templates/default-app/packages/app/src/App.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/App.tsx @@ -35,6 +35,8 @@ import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; import { RequirePermission } from '@backstage/plugin-permission-react'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; +import { NotificationsPage } from '@backstage/plugin-notifications'; +import { SignalsDisplay } from '@backstage/plugin-signals'; const app = createApp({ apis, @@ -94,6 +96,7 @@ const routes = ( } /> } /> + } /> ); @@ -101,6 +104,7 @@ export default app.createRoot( <> + {routes} diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx index 31fc08db7f..4163f34ede 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx @@ -27,6 +27,7 @@ import MenuIcon from '@material-ui/icons/Menu'; import SearchIcon from '@material-ui/icons/Search'; import { MyGroupsSidebarItem } from '@backstage/plugin-org'; import GroupIcon from '@material-ui/icons/People'; +import { NotificationsSidebarItem } from '@backstage/plugin-notifications'; const useSidebarLogoStyles = makeStyles({ root: { @@ -83,6 +84,8 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( + + } diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 8949a2ed0d..518683ffd7 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -27,6 +27,7 @@ "@backstage/plugin-catalog-backend-module-logs": "^{{version '@backstage/plugin-catalog-backend-module-logs'}}", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^{{version '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'}}", "@backstage/plugin-kubernetes-backend": "^{{version '@backstage/plugin-kubernetes-backend'}}", + "@backstage/plugin-notifications-backend": "^{{version '@backstage/plugin-notifications-backend'}}", "@backstage/plugin-permission-backend": "^{{version '@backstage/plugin-permission-backend'}}", "@backstage/plugin-permission-backend-module-allow-all-policy": "^{{version '@backstage/plugin-permission-backend-module-allow-all-policy'}}", "@backstage/plugin-permission-common": "^{{version '@backstage/plugin-permission-common'}}", @@ -34,11 +35,13 @@ "@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}", "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-scaffolder-backend-module-github": "^{{version '@backstage/plugin-scaffolder-backend-module-github'}}", + "@backstage/plugin-scaffolder-backend-module-notifications": "^{{version '@backstage/plugin-scaffolder-backend-module-notifications'}}", "@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}", "@backstage/plugin-search-backend-module-catalog": "^{{version '@backstage/plugin-search-backend-module-catalog'}}", "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", "@backstage/plugin-search-backend-module-techdocs": "^{{version '@backstage/plugin-search-backend-module-techdocs'}}", "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", + "@backstage/plugin-signals-backend": "^{{version '@backstage/plugin-signals-backend'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "app": "link:../app", "better-sqlite3": "^12.0.0", diff --git a/packages/create-app/templates/default-app/packages/backend/src/index.ts b/packages/create-app/templates/default-app/packages/backend/src/index.ts index 6d0a6f4ca5..cc2db7c3d4 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/index.ts @@ -12,8 +12,15 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-app-backend')); backend.add(import('@backstage/plugin-proxy-backend')); + +// scaffolder plugin backend.add(import('@backstage/plugin-scaffolder-backend')); backend.add(import('@backstage/plugin-scaffolder-backend-module-github')); +backend.add( + import('@backstage/plugin-scaffolder-backend-module-notifications'), +); + +// techdocs plugin backend.add(import('@backstage/plugin-techdocs-backend')); // auth plugin @@ -49,7 +56,11 @@ backend.add(import('@backstage/plugin-search-backend-module-pg')); backend.add(import('@backstage/plugin-search-backend-module-catalog')); backend.add(import('@backstage/plugin-search-backend-module-techdocs')); -// kubernetes +// kubernetes plugin backend.add(import('@backstage/plugin-kubernetes-backend')); +// notifications and signals plugins +backend.add(import('@backstage/plugin-notifications-backend')); +backend.add(import('@backstage/plugin-signals-backend')); + backend.start(); diff --git a/packages/create-app/templates/next-app/examples/template/template.yaml b/packages/create-app/templates/next-app/examples/template/template.yaml index f04c3241c5..2a20bd45ed 100644 --- a/packages/create-app/templates/next-app/examples/template/template.yaml +++ b/packages/create-app/templates/next-app/examples/template/template.yaml @@ -65,6 +65,18 @@ spec: input: repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }} catalogInfoPath: '/catalog-info.yaml' + + # Let's notify the user that the template has completed using the Notification action + - id: notify + name: Notify + action: notification:send + input: + recipients: entity + entityRefs: + - user:default/guest + title: 'Template executed' + info: 'Your template has been executed' + severity: 'normal' # Outputs are displayed to the user after a successful execution of the template. output: diff --git a/packages/create-app/templates/next-app/packages/app/package.json.hbs b/packages/create-app/templates/next-app/packages/app/package.json.hbs index 51a8956263..eb214e4ad1 100644 --- a/packages/create-app/templates/next-app/packages/app/package.json.hbs +++ b/packages/create-app/templates/next-app/packages/app/package.json.hbs @@ -19,9 +19,11 @@ "@backstage/frontend-defaults": "^{{ version '@backstage/frontend-defaults'}}", "@backstage/frontend-plugin-api": "^{{ version '@backstage/frontend-plugin-api'}}", "@backstage/plugin-catalog": "^{{ version '@backstage/plugin-catalog'}}", + "@backstage/plugin-notifications": "^{{ version '@backstage/plugin-notifications'}}", "@backstage/plugin-org": "^{{ version '@backstage/plugin-org'}}", "@backstage/plugin-scaffolder": "^{{ version '@backstage/plugin-scaffolder'}}", "@backstage/plugin-search": "^{{ version '@backstage/plugin-search'}}", + "@backstage/plugin-signals": "^{{ version '@backstage/plugin-signals'}}", "@backstage/plugin-user-settings": "^{{ version '@backstage/plugin-user-settings'}}", "@backstage/ui": "^{{ version '@backstage/ui'}}", "@material-ui/core": "^4.12.2", diff --git a/packages/create-app/templates/next-app/packages/backend/package.json.hbs b/packages/create-app/templates/next-app/packages/backend/package.json.hbs index 42afefd3b8..483c0b7a4e 100644 --- a/packages/create-app/templates/next-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/next-app/packages/backend/package.json.hbs @@ -27,6 +27,7 @@ "@backstage/plugin-catalog-backend-module-logs": "^{{version '@backstage/plugin-catalog-backend-module-logs'}}", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^{{version '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'}}", "@backstage/plugin-kubernetes-backend": "^{{version '@backstage/plugin-kubernetes-backend'}}", + "@backstage/plugin-notifications-backend": "^{{version '@backstage/plugin-notifications-backend'}}", "@backstage/plugin-permission-backend": "^{{version '@backstage/plugin-permission-backend'}}", "@backstage/plugin-permission-backend-module-allow-all-policy": "^{{version '@backstage/plugin-permission-backend-module-allow-all-policy'}}", "@backstage/plugin-permission-common": "^{{version '@backstage/plugin-permission-common'}}", @@ -34,11 +35,13 @@ "@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}", "@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}", "@backstage/plugin-scaffolder-backend-module-github": "^{{version '@backstage/plugin-scaffolder-backend-module-github'}}", + "@backstage/plugin-scaffolder-backend-module-notifications": "^{{version '@backstage/plugin-scaffolder-backend-module-notifications'}}", "@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}", "@backstage/plugin-search-backend-module-catalog": "^{{version '@backstage/plugin-search-backend-module-catalog'}}", "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", "@backstage/plugin-search-backend-module-techdocs": "^{{version '@backstage/plugin-search-backend-module-techdocs'}}", "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", + "@backstage/plugin-signals-backend": "^{{version '@backstage/plugin-signals-backend'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", "app": "link:../app", "better-sqlite3": "^9.0.0", diff --git a/packages/create-app/templates/next-app/packages/backend/src/index.ts b/packages/create-app/templates/next-app/packages/backend/src/index.ts index 6d0a6f4ca5..cc2db7c3d4 100644 --- a/packages/create-app/templates/next-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/next-app/packages/backend/src/index.ts @@ -12,8 +12,15 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-app-backend')); backend.add(import('@backstage/plugin-proxy-backend')); + +// scaffolder plugin backend.add(import('@backstage/plugin-scaffolder-backend')); backend.add(import('@backstage/plugin-scaffolder-backend-module-github')); +backend.add( + import('@backstage/plugin-scaffolder-backend-module-notifications'), +); + +// techdocs plugin backend.add(import('@backstage/plugin-techdocs-backend')); // auth plugin @@ -49,7 +56,11 @@ backend.add(import('@backstage/plugin-search-backend-module-pg')); backend.add(import('@backstage/plugin-search-backend-module-catalog')); backend.add(import('@backstage/plugin-search-backend-module-techdocs')); -// kubernetes +// kubernetes plugin backend.add(import('@backstage/plugin-kubernetes-backend')); +// notifications and signals plugins +backend.add(import('@backstage/plugin-notifications-backend')); +backend.add(import('@backstage/plugin-signals-backend')); + backend.start(); diff --git a/plugins/notifications-backend/src/service/router.test.ts b/plugins/notifications-backend/src/service/router.test.ts index 6c74fed41c..980762edbc 100644 --- a/plugins/notifications-backend/src/service/router.test.ts +++ b/plugins/notifications-backend/src/service/router.test.ts @@ -241,6 +241,9 @@ describe.each(databases.eachSupportedId())('createRouter (%s)', databaseId => { }, payload: { title: 'test notification', + metadata: { + attr: 1, + }, }, }); @@ -253,6 +256,9 @@ describe.each(databases.eachSupportedId())('createRouter (%s)', databaseId => { payload: { severity: 'normal', title: 'test notification', + metadata: { + attr: 1, + }, }, user: 'user:default/mock', }, diff --git a/plugins/notifications-common/package.json b/plugins/notifications-common/package.json index 66473d0237..9e1c544ba1 100644 --- a/plugins/notifications-common/package.json +++ b/plugins/notifications-common/package.json @@ -40,6 +40,7 @@ }, "dependencies": { "@backstage/config": "workspace:^", + "@backstage/types": "workspace:^", "@material-ui/icons": "^4.9.1" }, "devDependencies": { diff --git a/plugins/notifications-common/report.api.md b/plugins/notifications-common/report.api.md index 93889b206b..337c41b7b5 100644 --- a/plugins/notifications-common/report.api.md +++ b/plugins/notifications-common/report.api.md @@ -4,6 +4,7 @@ ```ts import { Config } from '@backstage/config'; +import { JsonValue } from '@backstage/types'; // @public (undocumented) export type ChannelSetting = { @@ -52,6 +53,9 @@ export type NotificationPayload = { topic?: string; scope?: string; icon?: string; + metadata?: { + [KMetadataKey in string]?: JsonValue; + }; }; // @public (undocumented) diff --git a/plugins/notifications-common/src/types.ts b/plugins/notifications-common/src/types.ts index 48f89cbbb4..4e49de79de 100644 --- a/plugins/notifications-common/src/types.ts +++ b/plugins/notifications-common/src/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { JsonValue } from '@backstage/types'; + /** @public */ export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; @@ -50,6 +52,10 @@ export type NotificationPayload = { * Optional notification icon */ icon?: string; + /** + * Optional additional customizable metadata. + */ + metadata?: { [KMetadataKey in string]?: JsonValue }; }; /** @public */ diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts index a8e844c827..da309b37ff 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts @@ -61,23 +61,22 @@ export class BackstageLoggerTransport extends Transport { const message = info[MESSAGE]; const level = info[LEVEL]; - const splat = info[SPLAT]; switch (level) { case 'error': - this.backstageLogger.error(String(message), ...splat); + this.backstageLogger.error(String(message)); break; case 'warn': - this.backstageLogger.warn(String(message), ...splat); + this.backstageLogger.warn(String(message)); break; case 'info': - this.backstageLogger.info(String(message), ...splat); + this.backstageLogger.info(String(message)); break; case 'debug': - this.backstageLogger.debug(String(message), ...splat); + this.backstageLogger.debug(String(message)); break; default: - this.backstageLogger.info(String(message), ...splat); + this.backstageLogger.info(String(message)); } this.taskContext.emitLog(message, { stepId: this.stepId }); diff --git a/yarn.lock b/yarn.lock index a3334417ab..c3cdc943dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5751,6 +5751,7 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" + "@backstage/types": "workspace:^" "@material-ui/icons": "npm:^4.9.1" languageName: unknown linkType: soft