Merge branch 'master' into yarn-workspaces-foreach
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-vault-backend': patch
|
||||
---
|
||||
|
||||
Removed lock inside recursion to avoid deadlocks
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-shortcuts': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `shortcuts` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-bitrise': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-import` ESLint rule to the Bitrise plugin to aid with the migration to Material UI v5.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Added a `EXPERIMENTAL_LAZY_COMPILATION` flag, which enables the experimental Webpack lazy compilation option in frontend builds.
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
'@backstage/plugin-code-coverage-backend': patch
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
'@backstage/plugin-azure-devops-backend': patch
|
||||
'@backstage/plugin-azure-sites-backend': patch
|
||||
'@backstage/plugin-permission-backend': patch
|
||||
'@backstage/plugin-airbrake-backend': patch
|
||||
'@backstage/plugin-devtools-backend': patch
|
||||
'@backstage/plugin-linguist-backend': patch
|
||||
'@backstage/plugin-periskop-backend': patch
|
||||
'@backstage/plugin-signals-backend': patch
|
||||
'@backstage/plugin-nomad-backend': patch
|
||||
'@backstage/plugin-vault-backend': patch
|
||||
---
|
||||
|
||||
Allow unauthenticated access to health check endpoint.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend': patch
|
||||
'@backstage/plugin-signals-backend': minor
|
||||
'@backstage/plugin-signals-node': minor
|
||||
---
|
||||
|
||||
**BREAKING** Type definition added to signal recipients
|
||||
|
||||
Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}`
|
||||
instead string entity references
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-rollbar': patch
|
||||
---
|
||||
|
||||
Adjusted MUI imports for better tree shaking.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-react': patch
|
||||
---
|
||||
|
||||
Create a generic React component for refreshing user cookie.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `sonarqube` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-scaffolder-node': patch
|
||||
---
|
||||
|
||||
Fixing the lost of the initial state after a task recovery.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@techdocs/cli': patch
|
||||
'@backstage/create-app': patch
|
||||
'@backstage/repo-tools': patch
|
||||
'@backstage/codemods': patch
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Removed the `ts-node` dev dependency.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Migrated the backend of the create app template to use the new backend system. For information on how to migrate your existing backend, see the [migration guide](https://backstage.io/docs/backend-system/building-backends/migrating).
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-gcalendar': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `gcalendar` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `user-settings` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-badges': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend-module-guest-provider': patch
|
||||
---
|
||||
|
||||
Fix issue for issuing a token when `guest` user does not exist in catalog
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-unprocessed-entities': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-codescene': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Codescene plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stackstorm': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `stackstorm` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-notifications-backend': minor
|
||||
'@backstage/plugin-notifications': minor
|
||||
---
|
||||
|
||||
Notifications-backend URL query parameters changed from `sort/sortOrder` to `orderField` and `created_after` to `createdAfter` to unify with other plugins.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
|
||||
---
|
||||
|
||||
Fixes an invalid line in the schema that was causing AJV to complain.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-xcmetrics': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `xcmetrics` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-playlist': patch
|
||||
---
|
||||
|
||||
Adjusted MUI imports for better tree shaking.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Updated dependency `react-idle-timer` to `5.7.2`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Updated dependency `graphiql` to `3.1.1`.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Updated dependency `@spotify/prettier-config` to `^15.0.0`.
|
||||
Updated dependency `@spotify/eslint-config-base` to `^15.0.0`.
|
||||
Updated dependency `@spotify/eslint-config-react` to `^15.0.0`.
|
||||
Updated dependency `@spotify/eslint-config-typescript` to `^15.0.0`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Lighthouse plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-sentry': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `sentry` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
'@backstage/plugin-techdocs-addons-test-utils': patch
|
||||
---
|
||||
|
||||
Use the new generic refresh user cookie provider.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-adr': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the ADR plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-vault': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `vault` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': minor
|
||||
---
|
||||
|
||||
The backend devlopment server transpilation has been replaced with a simplified solution based on SWC, which is already the transpiler used for tests. This fixed an issue where never versions of the `tsx` dependency had a new contract for signalling dependencies, breaking watch mode. This change fixed file watches as well as enables sourcemaps.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Add `relationsType` argument to `MembersListCard`.
|
||||
This can be used to display an aggregated user list for groups by default.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-code-climate': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Code-Climate plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `tech-insights` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend-module-atlassian-provider': patch
|
||||
---
|
||||
|
||||
Addressed OAuth flow issue in Atlassian auth module
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `stack-overflow` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
---
|
||||
|
||||
Add location analyzer when installing the module
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-splunk-on-call': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `splunk-on-call` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
The experimental feature discovery service exported at the `/alpha` sub-path will no longer attempt to load packages that are not Backstage backend packages.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-signals': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the `signals` plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-unprocessed': minor
|
||||
'@backstage/plugin-catalog-unprocessed-entities': minor
|
||||
'@backstage/plugin-catalog-unprocessed-entities-common': patch
|
||||
---
|
||||
|
||||
**BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` constructor is now private, and have been moved to using the static `.create` method instead which now requires a `PermissionService` and `DiscoveryService`.
|
||||
|
||||
If you're using this module in the old backend system you'll need to migrate to using the `.create` method and pass in the new required parameters in `packages/backend/src/plugins/catalog.ts`.
|
||||
|
||||
No changes should be required if you're using the new backend system.
|
||||
|
||||
```diff
|
||||
- const unprocessed = new UnprocessedEntitiesModule(
|
||||
- await env.database.getClient(),
|
||||
- router,
|
||||
- );
|
||||
+ const unprocessed = UnprocessedEntitiesModule.create({
|
||||
+ database: await env.database.getClient(),
|
||||
+ router,
|
||||
+ permissions: env.permissions,
|
||||
+ discovery: env.discovery,
|
||||
+ });
|
||||
|
||||
unprocessed.registerRoutes();
|
||||
```
|
||||
|
||||
Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
---
|
||||
|
||||
Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-kafka': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Kafka plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Jenkins plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-code-coverage': patch
|
||||
---
|
||||
|
||||
Added ESLint rule `no-top-level-material-ui-4-imports` in the Code-Coverage plugin to migrate the Material UI imports.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-fossa': patch
|
||||
---
|
||||
|
||||
Adjusted MUI imports for better tree shaking
|
||||
@@ -51,17 +51,17 @@ jobs:
|
||||
working-directory: ./example-app
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
with:
|
||||
context: './example-app'
|
||||
file: ./example-app/packages/backend/Dockerfile
|
||||
|
||||
@@ -66,6 +66,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
|
||||
uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -43,6 +43,6 @@ jobs:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
NODE_OPTIONS: --max-old-space-size=7168
|
||||
- name: Update Github issues
|
||||
run: yarn ts-node scripts/snyk-github-issue-sync.ts
|
||||
run: ./scripts/snyk-github-issue-sync.ts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -58,6 +58,6 @@ jobs:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
NODE_OPTIONS: --max-old-space-size=7168
|
||||
- name: Upload Snyk report
|
||||
uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
|
||||
uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
yarn workspace example-backend build
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
|
||||
|
||||
- name: Generate UUID image name
|
||||
id: uuid
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
tags: type=raw,value=60d
|
||||
|
||||
- name: Build Image
|
||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
with:
|
||||
context: .
|
||||
file: packages/backend/Dockerfile
|
||||
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
|
||||
uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
|
||||
uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -80,4 +80,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
|
||||
uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7
|
||||
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
- run: yarn build-storybook
|
||||
|
||||
- uses: chromaui/action@fd0e276c344bab4dc69a023fdf89ffb9b79b3b31 # v11
|
||||
- uses: chromaui/action@306092d42c0743800aadf544ee263cbc56598b1b # v11
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# projectToken intentionally shared to allow collaborators to run Chromatic on forks
|
||||
|
||||
@@ -95,6 +95,7 @@ The role of the notifications plugin is to manage the lifecycle of notifications
|
||||
The notification backend stores notification using the [database service](https://backstage.io/docs/backend-system/core-services/index#database). In particular it needs to store the following information for each notification:
|
||||
|
||||
- ID
|
||||
- Recipients
|
||||
- Read date
|
||||
- Saved status
|
||||
- Creation date
|
||||
@@ -105,7 +106,6 @@ The notification backend stores notification using the [database service](https:
|
||||
- Origin
|
||||
- Link (optional)
|
||||
- Additional links (optional)
|
||||
- Recipients
|
||||
- Severity (optional, default normal)
|
||||
- Topic (optional)
|
||||
- Scope (optional)
|
||||
@@ -153,7 +153,9 @@ The `notification-backend` does not provide any new permissions, since creating
|
||||
|
||||
The `notification-backend` shall provide necessary parameters for paging and filtering notifications from the frontend.
|
||||
|
||||
The notification frontend plugin provides a UI for viewing notifications, which in the initial implementation can be as simple as needed. The only requirement is that a user is able to view recent notifications and distinguish between read and unread notifications. A notification as marked as read once it has been interacted with. The frontend plugin also subscribes to the notifications signal channel and alerts the user when a new notification is received.
|
||||
The notification frontend plugin provides a UI for viewing notifications, which in the initial implementation can be as simple as needed. The only requirement is that a user is able to view recent notifications and distinguish between read and unread notifications. The frontend plugin also subscribes to the notifications signal channel and alerts the user when a new notification is received.
|
||||
|
||||
Both the individual and broadcasted messages are rendered together in a single list. There will be a filter choosing of of those types or `all`.
|
||||
|
||||
### Architecture Overview
|
||||
|
||||
@@ -165,11 +167,12 @@ The components that are presented with dashed lines are not directly part of thi
|
||||
|
||||
Let's walk through the process of sending of a notification to a user:
|
||||
|
||||
1. A backend plugin that wants to send a notification to a user uses the `NotificationService`, which in turn makes a POST request to the notification backend. The request contains a filter to select the target users, as well as the notification payload.
|
||||
1. A backend plugin that wants to send a notification to a user uses the `NotificationService`, which in turn makes a POST request to the notification backend. The request contains either a filter to select the target users or type `broadcast`, as well as the notification payload.
|
||||
|
||||
1b. As the notification backend handles the request it could optionally invoke a series of notification processors. These processors can be used to transform the notification payload, send the notification through other channels, and decide whether the regular notification flow should continue or not. This step is not in scope for this proposal.
|
||||
|
||||
2. The notification backend stores the received notification in its database. At this point the notification is available from the notification backend's read API.
|
||||
|
||||
3. The notification backend published an event to the event bus on the `'signal'` topic. This event payload contains the signaling channel, in this case `'notifications'`, as well as the target user ID and the notification ID, but not the notification payload.
|
||||
4. Each instance of the signal backend plugin subscribes to the `'signal'` topic and receives the event.
|
||||
5. Each signal backend instance has a set of push channels set up to online users. The incoming event is filtered based on the target user ID and the signaling is pushed through all connections with a matching user ID.
|
||||
@@ -214,6 +217,7 @@ export type NotificationPayload = {
|
||||
export type Notification = {
|
||||
id: string;
|
||||
userRef: string;
|
||||
broadcasted: boolean;
|
||||
created: Date;
|
||||
saved?: Date;
|
||||
read?: Date;
|
||||
@@ -232,12 +236,29 @@ interface NotificationService {
|
||||
}
|
||||
```
|
||||
|
||||
Each notification is always routed to individual users unless it's a broadcast. The `notification-backend` will figure out which users will receive a notification based on the `recipients` parameter, resolving it to the concrete list of users at the time of sending the notification.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Each notification is always routed to individual users unless its type is `broadcast`.
|
||||
|
||||
##### Individual user notifications
|
||||
|
||||
The `notification-backend` will figure out which users will receive a notification based on the `recipients` parameter, resolving it to the concrete list of users at the time of sending the notification.
|
||||
|
||||
##### Broadcasted notifications
|
||||
|
||||
Broadcasted messages are stored in a separate database table for performance reasons and simplicity of queries.
|
||||
There is only one record per message.
|
||||
|
||||
To maintain flags, there will be another table with 1:N relation. This table will contain `user`, `read`, `saved` and `updated` columns, linked via message ID foreign-key.
|
||||
This table of flags is not prefilled on a broadcast message creation but a record is added when there is an updating POST by a particular user.
|
||||
|
||||
When notifications are queried, two (main) database queries are issued - for both the individual and broadcasted messages.
|
||||
Their results are merged into a single response but setting the `broadcasted` flag based on source.
|
||||
|
||||
If an individual message is queried (via GET `/notifications/:id`), both the individual and broadcasted tables are searched. The first result found is used for the response.
|
||||
|
||||
#### `SignalService`
|
||||
|
||||
```ts
|
||||
@@ -269,7 +290,6 @@ Example signal payload for a new notification:
|
||||
|
||||
#### Future considerations and BEP TODO
|
||||
|
||||
- Broadcast messages are to be saved to a separate table for performance reasons
|
||||
- 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
|
||||
|
||||
@@ -4,8 +4,8 @@ status: provisional
|
||||
authors:
|
||||
- 'bnechyporenko@bol.com'
|
||||
- 'benjaminl@spotify.com'
|
||||
owners:
|
||||
- @backstage/scaffolder-maintainers
|
||||
owners:
|
||||
- '@backstage/scaffolder-maintainers'
|
||||
project-areas:
|
||||
- scaffolder
|
||||
creation-date: 2024-01-31
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: Scaffolder Action Rollback
|
||||
status: provisional
|
||||
authors:
|
||||
- 'bnechyporenko@bol.com'
|
||||
- 'benjaminl@spotify.com'
|
||||
owners:
|
||||
- '@backstage/scaffolder-maintainers'
|
||||
project-areas:
|
||||
- scaffolder
|
||||
creation-date: 2024-03-13
|
||||
---
|
||||
|
||||
# BEP: <!-- Your short, descriptive title -->
|
||||
|
||||
[**Discussion Issue**](https://github.com/backstage/backstage/issues/NNNNN)
|
||||
|
||||
- [Summary](#summary)
|
||||
- [Motivation](#motivation)
|
||||
- [Goals](#goals)
|
||||
- [Non-Goals](#non-goals)
|
||||
- [Proposal](#proposal)
|
||||
- [Design Details](#design-details)
|
||||
- [Release Plan](#release-plan)
|
||||
- [Dependencies](#dependencies)
|
||||
- [Alternatives](#alternatives)
|
||||
|
||||
## Summary
|
||||
|
||||
Introducing the rollback to scaffolder actions provides the mean to come back to the initial state.
|
||||
|
||||
## Motivation
|
||||
|
||||
The aim is to help to mitigate the issue of manual clean up the partially created resources.
|
||||
|
||||
### Goals
|
||||
|
||||
- We will extend action's API to be able to run rollback for failed tasks
|
||||
- Rollback will be optional
|
||||
|
||||
### Non-Goals
|
||||
|
||||
We will not cover all built-in actions with a rollback functionality
|
||||
|
||||
## Proposal
|
||||
|
||||
Rollback is going to be performed:
|
||||
|
||||
- when user manually decide to perform this action.
|
||||
- task has to be recovered and TaskRecoverStrategy set to 'rollback'
|
||||
|
||||
## Design Details
|
||||
|
||||
We are going to introduce an extra function in action API which will look like:
|
||||
|
||||
```typescript
|
||||
const createPublishGitHubAction = createTemplateAction({
|
||||
id: 'publish:github',
|
||||
async handler() {},
|
||||
async rollback() {},
|
||||
});
|
||||
```
|
||||
|
||||
## Release Plan
|
||||
|
||||
<!--
|
||||
This section should describe the rollout process for any new features. It must take our version policies into account and plan for a phased rollout if this change affects any existing stable APIs.
|
||||
|
||||
If there is any particular feedback to be gathered during the rollout, this should be described here as well.
|
||||
-->
|
||||
|
||||
## Dependencies
|
||||
|
||||
<!--
|
||||
List any dependencies that this work has on other BEPs or features.
|
||||
-->
|
||||
|
||||
## Alternatives
|
||||
|
||||
<!--
|
||||
What other approaches did you consider, and why did you rule them out? These do
|
||||
not need to be as detailed as the proposal, but should include enough
|
||||
information to express the idea and why it was not acceptable.
|
||||
-->
|
||||
@@ -40,6 +40,7 @@ choice below.
|
||||
| [Google Analytics 4][ga4] | Yes ✅ |
|
||||
| [New Relic Browser][newrelic-browser] | Community ✅ |
|
||||
| [Matomo][matomo] | Community ✅ |
|
||||
| [Quantum Metric][qm] | Community ✅ |
|
||||
|
||||
To suggest an integration, please [open an issue][add-tool] for the analytics
|
||||
tool your organization uses. Or jump to [Writing Integrations][int-howto] to
|
||||
@@ -48,6 +49,7 @@ learn how to contribute the integration yourself!
|
||||
[ga]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md
|
||||
[ga4]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga4/README.md
|
||||
[newrelic-browser]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-newrelic-browser/README.md
|
||||
[qm]: https://github.com/quantummetric/analytics-module-qm/blob/main/README.md
|
||||
[matomo]: https://github.com/janus-idp/backstage-plugins/blob/main/plugins/analytics-module-matomo/README.md
|
||||
[add-tool]: https://github.com/backstage/backstage/issues/new?assignees=&labels=plugin&template=plugin_template.md&title=%5BAnalytics+Module%5D+THE+ANALYTICS+TOOL+TO+INTEGRATE
|
||||
[int-howto]: #writing-integrations
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'Analytics Module: Quantum Metric'
|
||||
author: Quantum Metric
|
||||
authorUrl: https://github.com/quantummetric
|
||||
category: Monitoring
|
||||
description: Track usage of your Backstage instance using Quantum Metric.
|
||||
documentation: https://github.com/quantummetric/analytics-module-qm/blob/main/README.md
|
||||
iconUrl: /img/qm-icon.png
|
||||
npmPackageName: '@quantum-metric/plugin-analytics-module-qm'
|
||||
addedDate: '2024-03-15'
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.1.1",
|
||||
"@spotify/prettier-config": "^14.0.0",
|
||||
"@spotify/prettier-config": "^15.0.0",
|
||||
"@tsconfig/docusaurus": "^2.0.0",
|
||||
"@types/luxon": "^3.0.0",
|
||||
"@types/webpack-env": "^1.18.0",
|
||||
|
||||
@@ -81,6 +81,11 @@ const Community = () => {
|
||||
url: 'https://roadie.io/',
|
||||
logo: 'img/partner-logo-roadie.png',
|
||||
},
|
||||
{
|
||||
name: 'solo.io',
|
||||
url: 'https://www.solo.io/spotlight/',
|
||||
logo: 'img/partner-logo-solo.png',
|
||||
},
|
||||
{
|
||||
name: 'ThoughtWorks',
|
||||
url: 'https://www.thoughtworks.com/about-us/partnerships/technology/backstage-by-spotify',
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
+54
-54
@@ -2532,12 +2532,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@spotify/prettier-config@npm:^14.0.0":
|
||||
version: 14.1.3
|
||||
resolution: "@spotify/prettier-config@npm:14.1.3"
|
||||
"@spotify/prettier-config@npm:^15.0.0":
|
||||
version: 15.0.0
|
||||
resolution: "@spotify/prettier-config@npm:15.0.0"
|
||||
peerDependencies:
|
||||
prettier: 2.x
|
||||
checksum: 0c64ec0de9be5ae24a9b2a8f5c3af6c02306a47f54fffbd014852b00245fc939f3131eeeac8e906dfbb6aa86a5c0213b7f35623badad072979068f8cd69c316f
|
||||
checksum: aa5ec5739427f9acdb9d62ae6c04f04a344898567239f7ee45c75c6205ebdffbc61747ea8de6e83baf0bc3785359967de4b7097a8723c4b4063ff57dc5cb6c44
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2697,90 +2697,90 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-darwin-arm64@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-darwin-arm64@npm:1.4.2"
|
||||
"@swc/core-darwin-arm64@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-darwin-arm64@npm:1.4.8"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-darwin-x64@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-darwin-x64@npm:1.4.2"
|
||||
"@swc/core-darwin-x64@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-darwin-x64@npm:1.4.8"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm-gnueabihf@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.2"
|
||||
"@swc/core-linux-arm-gnueabihf@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.8"
|
||||
conditions: os=linux & cpu=arm
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm64-gnu@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-linux-arm64-gnu@npm:1.4.2"
|
||||
"@swc/core-linux-arm64-gnu@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-linux-arm64-gnu@npm:1.4.8"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-arm64-musl@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-linux-arm64-musl@npm:1.4.2"
|
||||
"@swc/core-linux-arm64-musl@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-linux-arm64-musl@npm:1.4.8"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-x64-gnu@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-linux-x64-gnu@npm:1.4.2"
|
||||
"@swc/core-linux-x64-gnu@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-linux-x64-gnu@npm:1.4.8"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-linux-x64-musl@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-linux-x64-musl@npm:1.4.2"
|
||||
"@swc/core-linux-x64-musl@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-linux-x64-musl@npm:1.4.8"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-arm64-msvc@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-win32-arm64-msvc@npm:1.4.2"
|
||||
"@swc/core-win32-arm64-msvc@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-win32-arm64-msvc@npm:1.4.8"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-ia32-msvc@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-win32-ia32-msvc@npm:1.4.2"
|
||||
"@swc/core-win32-ia32-msvc@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-win32-ia32-msvc@npm:1.4.8"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core-win32-x64-msvc@npm:1.4.2":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core-win32-x64-msvc@npm:1.4.2"
|
||||
"@swc/core-win32-x64-msvc@npm:1.4.8":
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core-win32-x64-msvc@npm:1.4.8"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/core@npm:^1.3.46":
|
||||
version: 1.4.2
|
||||
resolution: "@swc/core@npm:1.4.2"
|
||||
version: 1.4.8
|
||||
resolution: "@swc/core@npm:1.4.8"
|
||||
dependencies:
|
||||
"@swc/core-darwin-arm64": 1.4.2
|
||||
"@swc/core-darwin-x64": 1.4.2
|
||||
"@swc/core-linux-arm-gnueabihf": 1.4.2
|
||||
"@swc/core-linux-arm64-gnu": 1.4.2
|
||||
"@swc/core-linux-arm64-musl": 1.4.2
|
||||
"@swc/core-linux-x64-gnu": 1.4.2
|
||||
"@swc/core-linux-x64-musl": 1.4.2
|
||||
"@swc/core-win32-arm64-msvc": 1.4.2
|
||||
"@swc/core-win32-ia32-msvc": 1.4.2
|
||||
"@swc/core-win32-x64-msvc": 1.4.2
|
||||
"@swc/core-darwin-arm64": 1.4.8
|
||||
"@swc/core-darwin-x64": 1.4.8
|
||||
"@swc/core-linux-arm-gnueabihf": 1.4.8
|
||||
"@swc/core-linux-arm64-gnu": 1.4.8
|
||||
"@swc/core-linux-arm64-musl": 1.4.8
|
||||
"@swc/core-linux-x64-gnu": 1.4.8
|
||||
"@swc/core-linux-x64-musl": 1.4.8
|
||||
"@swc/core-win32-arm64-msvc": 1.4.8
|
||||
"@swc/core-win32-ia32-msvc": 1.4.8
|
||||
"@swc/core-win32-x64-msvc": 1.4.8
|
||||
"@swc/counter": ^0.1.2
|
||||
"@swc/types": ^0.1.5
|
||||
peerDependencies:
|
||||
@@ -2809,7 +2809,7 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
"@swc/helpers":
|
||||
optional: true
|
||||
checksum: b17afda692b2627d3a82e589f1b29cef31bdee626a2dd997d78312dcbfc6eb701850fbab22e85f02b1261da39f0b0afb6a236c6065f6d0d7478cff939ca5a888
|
||||
checksum: 3284e64fe72896d1be8637f7fdcbba575d86e02da056a8c5208c93877250bfb1922fc5194281926650d5694e2434b7906efc0db8925769a4558f5fbd93028fd6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3855,7 +3855,7 @@ __metadata:
|
||||
"@docusaurus/module-type-aliases": ^3.1.1
|
||||
"@docusaurus/plugin-client-redirects": ^3.1.1
|
||||
"@docusaurus/preset-classic": ^3.1.1
|
||||
"@spotify/prettier-config": ^14.0.0
|
||||
"@spotify/prettier-config": ^15.0.0
|
||||
"@swc/core": ^1.3.46
|
||||
"@tsconfig/docusaurus": ^2.0.0
|
||||
"@types/luxon": ^3.0.0
|
||||
@@ -5770,12 +5770,12 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"follow-redirects@npm:^1.0.0":
|
||||
version: 1.15.4
|
||||
resolution: "follow-redirects@npm:1.15.4"
|
||||
version: 1.15.6
|
||||
resolution: "follow-redirects@npm:1.15.6"
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
checksum: e178d1deff8b23d5d24ec3f7a94cde6e47d74d0dc649c35fc9857041267c12ec5d44650a0c5597ef83056ada9ea6ca0c30e7c4f97dbf07d035086be9e6a5b7b6
|
||||
checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10392,15 +10392,15 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"sass@npm:^1.57.1":
|
||||
version: 1.71.1
|
||||
resolution: "sass@npm:1.71.1"
|
||||
version: 1.72.0
|
||||
resolution: "sass@npm:1.72.0"
|
||||
dependencies:
|
||||
chokidar: ">=3.0.0 <4.0.0"
|
||||
immutable: ^4.0.0
|
||||
source-map-js: ">=0.6.2 <2.0.0"
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 19c4939d3042eb9459d462bbd27b1f576fa18034e23c87ca0005b87effdee431c16503b5a785edcdcde1a76dfb804716d9ad42c85a78968ac3825d515e45cb53
|
||||
checksum: f420079c7d51660b7256ee52463c1499ede36f7fd5c8ef50c687451777ad641509001454dea45244073cedd7c00e7a3bc1c362e55206ac6686171b994edb41e4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
+2
-3
@@ -104,8 +104,8 @@
|
||||
"@changesets/cli": "^2.14.0",
|
||||
"@octokit/rest": "^19.0.3",
|
||||
"@playwright/test": "^1.32.3",
|
||||
"@spotify/eslint-plugin": "^14.1.3",
|
||||
"@spotify/prettier-config": "^14.0.0",
|
||||
"@spotify/eslint-plugin": "^15.0.0",
|
||||
"@spotify/prettier-config": "^15.0.0",
|
||||
"@techdocs/cli": "workspace:*",
|
||||
"@types/node": "^18.17.8",
|
||||
"@types/webpack": "^5.28.0",
|
||||
@@ -127,7 +127,6 @@
|
||||
"shx": "^0.3.2",
|
||||
"sloc": "^0.3.1",
|
||||
"sort-package-json": "^2.8.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "~5.1.0"
|
||||
},
|
||||
"packageManager": "yarn@3.8.1",
|
||||
|
||||
+25
-25
@@ -1,17 +1,39 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.93-next.2",
|
||||
"private": true,
|
||||
"backstage": {
|
||||
"role": "frontend"
|
||||
},
|
||||
"bundled": true,
|
||||
"private": true,
|
||||
"homepage": "https://backstage.io",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/backstage/backstage",
|
||||
"directory": "packages/app"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build",
|
||||
"clean": "backstage-cli package clean",
|
||||
"lint": "backstage-cli package lint",
|
||||
"start": "cross-env EXPERIMENTAL_LAZY_COMPILATION=1 backstage-cli package start",
|
||||
"test": "backstage-cli package test"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/app-defaults": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
@@ -121,27 +143,5 @@
|
||||
"@types/zen-observable": "^0.8.0",
|
||||
"cross-env": "^7.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build",
|
||||
"clean": "backstage-cli package clean",
|
||||
"test": "backstage-cli package test",
|
||||
"lint": "backstage-cli package lint"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"license": "Apache-2.0"
|
||||
"bundled": true
|
||||
}
|
||||
|
||||
@@ -29,6 +29,13 @@ import { resolve as resolvePath, dirname } from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import { BackstagePackageJson } from '@backstage/cli-node';
|
||||
|
||||
const DETECTED_PACKAGE_ROLES = [
|
||||
'node-library',
|
||||
'backend',
|
||||
'backend-plugin',
|
||||
'backend-plugin-module',
|
||||
];
|
||||
|
||||
/** @internal */
|
||||
async function findClosestPackageDir(
|
||||
searchDir: string,
|
||||
@@ -106,8 +113,11 @@ class PackageDiscoveryService implements FeatureDiscoveryService {
|
||||
const depPkg = require(require.resolve(`${name}/package.json`, {
|
||||
paths: [packageDir],
|
||||
})) as BackstagePackageJson;
|
||||
if (!depPkg?.backstage || depPkg?.backstage?.role === 'cli') {
|
||||
continue; // Not a backstage package, ignore
|
||||
if (
|
||||
!depPkg?.backstage?.role ||
|
||||
!DETECTED_PACKAGE_ROLES.includes(depPkg.backstage.role)
|
||||
) {
|
||||
continue; // Not a backstage backend package, ignore
|
||||
}
|
||||
|
||||
const exportedModulePaths = [
|
||||
|
||||
@@ -246,7 +246,7 @@ describe('ZipArchiveResponse', () => {
|
||||
const filesPromise = res.files();
|
||||
|
||||
await expect(filesPromise).rejects.toThrow(
|
||||
'invalid comment length. expected: 55. found: 0',
|
||||
/Invalid comment length. Expected: 55. Found: 0/,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -37,11 +37,15 @@ export default async function createPlugin(
|
||||
|
||||
const { processingEngine, router } = await builder.build();
|
||||
|
||||
const unprocessed = new UnprocessedEntitiesModule(
|
||||
await env.database.getClient(),
|
||||
const unprocessed = UnprocessedEntitiesModule.create({
|
||||
database: await env.database.getClient(),
|
||||
router,
|
||||
);
|
||||
permissions: env.permissions,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
|
||||
unprocessed.registerRoutes();
|
||||
|
||||
await processingEngine.start();
|
||||
return router;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,6 @@ const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src'));
|
||||
if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) {
|
||||
require('..');
|
||||
} else {
|
||||
require('ts-node').register({
|
||||
transpileOnly: true,
|
||||
/* eslint-disable-next-line no-restricted-syntax */
|
||||
project: path.resolve(__dirname, '../../../tsconfig.json'),
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
},
|
||||
});
|
||||
|
||||
require('@backstage/cli/config/nodeTransform.cjs');
|
||||
require('../src');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const { transformSync } = require('@swc/core');
|
||||
const { addHook } = require('pirates');
|
||||
|
||||
addHook(
|
||||
(code, filename) => {
|
||||
const transformed = transformSync(code, {
|
||||
filename,
|
||||
sourceMaps: 'inline',
|
||||
module: { type: 'commonjs' },
|
||||
jsc: {
|
||||
target: 'es2022',
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
},
|
||||
},
|
||||
});
|
||||
process.send?.({ type: 'watch', path: filename });
|
||||
return transformed.code;
|
||||
},
|
||||
{ extensions: ['.ts', '.cts'], ignoreNodeModules: true },
|
||||
);
|
||||
|
||||
addHook(
|
||||
(code, filename) => {
|
||||
process.send?.({ type: 'watch', path: filename });
|
||||
return code;
|
||||
},
|
||||
{ extensions: ['.js', '.cjs'], ignoreNodeModules: true },
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
# Knip report
|
||||
|
||||
## Unused dependencies (27)
|
||||
## Unused dependencies (28)
|
||||
|
||||
| Name | Location | Severity |
|
||||
| :------------------------------- | :----------- | :------- |
|
||||
@@ -25,6 +25,7 @@
|
||||
| @swc/core | package.json | error |
|
||||
| @swc/jest | package.json | error |
|
||||
| esbuild | package.json | error |
|
||||
| pirates | package.json | error |
|
||||
| postcss | package.json | error |
|
||||
| process | package.json | error |
|
||||
| sucrase | package.json | error |
|
||||
@@ -32,7 +33,7 @@
|
||||
| glob | package.json | error |
|
||||
| util | package.json | error |
|
||||
|
||||
## Unused devDependencies (12)
|
||||
## Unused devDependencies (11)
|
||||
|
||||
| Name | Location | Severity |
|
||||
| :-------------------------------------- | :----------- | :------- |
|
||||
@@ -46,7 +47,6 @@
|
||||
| @types/svgo | package.json | error |
|
||||
| @types/ejs | package.json | error |
|
||||
| nodemon | package.json | error |
|
||||
| ts-node | package.json | error |
|
||||
| del | package.json | error |
|
||||
|
||||
## Referenced optional peerDependencies (4)
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.0",
|
||||
"@rollup/plugin-yaml": "^4.0.0",
|
||||
"@spotify/eslint-config-base": "^14.0.0",
|
||||
"@spotify/eslint-config-react": "^14.0.0",
|
||||
"@spotify/eslint-config-typescript": "^14.0.0",
|
||||
"@spotify/eslint-config-base": "^15.0.0",
|
||||
"@spotify/eslint-config-react": "^15.0.0",
|
||||
"@spotify/eslint-config-typescript": "^15.0.0",
|
||||
"@sucrase/webpack-loader": "^2.0.0",
|
||||
"@svgr/core": "6.5.x",
|
||||
"@svgr/plugin-jsx": "6.5.x",
|
||||
@@ -114,6 +114,7 @@
|
||||
"ora": "^5.3.0",
|
||||
"p-limit": "^3.1.0",
|
||||
"p-queue": "^6.6.2",
|
||||
"pirates": "^4.0.6",
|
||||
"postcss": "^8.1.0",
|
||||
"process": "^0.11.10",
|
||||
"react-dev-utils": "^12.0.0-next.60",
|
||||
@@ -131,7 +132,6 @@
|
||||
"swc-loader": "^0.2.3",
|
||||
"tar": "^6.1.12",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"tsx": "^4.0.0",
|
||||
"util": "^0.12.3",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-dev-server": "^4.7.3",
|
||||
@@ -168,10 +168,13 @@
|
||||
"@types/tar": "^6.1.1",
|
||||
"@types/terser-webpack-plugin": "^5.0.4",
|
||||
"@types/yarnpkg__lockfile": "^1.1.4",
|
||||
"@vitejs/plugin-react": "^4.0.4",
|
||||
"del": "^7.0.0",
|
||||
"msw": "^1.0.0",
|
||||
"nodemon": "^3.0.1",
|
||||
"ts-node": "^10.0.0"
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-node-polyfills": "^0.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitejs/plugin-react": "^4.0.4",
|
||||
|
||||
@@ -224,6 +224,9 @@ export async function createConfig(
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
experiments: {
|
||||
lazyCompilation: yn(process.env.EXPERIMENTAL_LAZY_COMPILATION),
|
||||
},
|
||||
plugins,
|
||||
...(withCache
|
||||
? {
|
||||
|
||||
@@ -22,22 +22,16 @@ import { ctrlc } from 'ctrlc-windows';
|
||||
import { IpcServer } from './IpcServer';
|
||||
import { ServerDataStore } from './ServerDataStore';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { fileURLToPath, pathToFileURL } from 'url';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { isAbsolute as isAbsolutePath } from 'path';
|
||||
import { paths } from '../paths';
|
||||
import spawn from 'cross-spawn';
|
||||
|
||||
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(Number);
|
||||
const supportsModuleLoaderRegister =
|
||||
nodeMajor > 20 ||
|
||||
(nodeMajor === 20 && nodeMinor >= 6) ||
|
||||
(nodeMajor === 18 && nodeMinor >= 19);
|
||||
|
||||
const loaderArgs = [
|
||||
'--enable-source-maps',
|
||||
'--require',
|
||||
require.resolve('tsx/preflight'),
|
||||
supportsModuleLoaderRegister ? '--import' : '--loader',
|
||||
pathToFileURL(require.resolve('tsx')).toString(), // Windows prefers a URL here
|
||||
require.resolve('@backstage/cli/config/nodeTransform.cjs'),
|
||||
// TODO: Support modules, although there's currently no way to load them since import() is transpiled tp require()
|
||||
];
|
||||
|
||||
export async function startBackendExperimental(options: BackendServeOptions) {
|
||||
@@ -51,11 +45,21 @@ export async function startBackendExperimental(options: BackendServeOptions) {
|
||||
ServerDataStore.bind(server);
|
||||
|
||||
let exiting = false;
|
||||
let firstStart = true;
|
||||
let child: ChildProcess | undefined;
|
||||
let watcher: FSWatcher | undefined = undefined;
|
||||
let shutdownPromise: Promise<void> | undefined = undefined;
|
||||
|
||||
const watchedPaths = new Set<string>();
|
||||
|
||||
const restart = debounce(async () => {
|
||||
if (firstStart) {
|
||||
firstStart = false;
|
||||
} else {
|
||||
console.log();
|
||||
console.log('Change detected, restarting the development server...');
|
||||
console.log();
|
||||
}
|
||||
// If a re-trigger happens during an existing shutdown, we just ignore it
|
||||
if (shutdownPromise) {
|
||||
return;
|
||||
@@ -115,14 +119,18 @@ export async function startBackendExperimental(options: BackendServeOptions) {
|
||||
|
||||
// This captures messages sent by @esbuild-kit/cjs-loader
|
||||
child.on('message', (data: { type?: string } | null) => {
|
||||
if (typeof data === 'object' && data?.type === 'dependency') {
|
||||
if (!watcher) {
|
||||
return;
|
||||
}
|
||||
if (typeof data === 'object' && data?.type === 'watch') {
|
||||
let path = (data as { path: string }).path;
|
||||
if (path.startsWith('file:')) {
|
||||
path = fileURLToPath(path);
|
||||
}
|
||||
|
||||
if (isAbsolutePath(path)) {
|
||||
watcher?.add(path);
|
||||
if (isAbsolutePath(path) && !watchedPaths.has(path)) {
|
||||
watchedPaths.add(path);
|
||||
watcher.add(path);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -130,7 +138,7 @@ export async function startBackendExperimental(options: BackendServeOptions) {
|
||||
|
||||
restart();
|
||||
|
||||
watcher = watch([], {
|
||||
watcher = watch(['./package.json'], {
|
||||
cwd: process.cwd(),
|
||||
ignoreInitial: true,
|
||||
ignorePermissionErrors: true,
|
||||
|
||||
@@ -24,14 +24,6 @@ const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src'));
|
||||
if (!isLocal) {
|
||||
require('..');
|
||||
} else {
|
||||
require('ts-node').register({
|
||||
transpileOnly: true,
|
||||
/* eslint-disable-next-line no-restricted-syntax */
|
||||
project: path.resolve(__dirname, '../../../tsconfig.json'),
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
},
|
||||
});
|
||||
|
||||
require('@backstage/cli/config/nodeTransform.cjs');
|
||||
require('../src');
|
||||
}
|
||||
|
||||
@@ -1,8 +1,2 @@
|
||||
# Knip report
|
||||
|
||||
## Unused devDependencies (1)
|
||||
|
||||
| Name | Location | Severity |
|
||||
| :------ | :----------- | :------- |
|
||||
| ts-node | package.json | error |
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@types/jscodeshift": "^0.11.0",
|
||||
"@types/node": "^18.17.8",
|
||||
"ts-node": "^10.0.0"
|
||||
"@types/node": "^18.17.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"rc-progress": "3.5.1",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-hook-form": "^7.12.2",
|
||||
"react-idle-timer": "5.6.2",
|
||||
"react-idle-timer": "5.7.2",
|
||||
"react-markdown": "^8.0.0",
|
||||
"react-sparklines": "^1.7.0",
|
||||
"react-syntax-highlighter": "^15.4.5",
|
||||
|
||||
@@ -24,15 +24,6 @@ const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src'));
|
||||
if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) {
|
||||
require('..');
|
||||
} else {
|
||||
// Only used for development, so should be a devDependency
|
||||
// eslint-disable-next-line @backstage/no-undeclared-imports
|
||||
require('ts-node').register({
|
||||
transpileOnly: true,
|
||||
project: path.resolve(__dirname, '../../../tsconfig.json'),
|
||||
compilerOptions: {
|
||||
module: 'CommonJS',
|
||||
},
|
||||
});
|
||||
|
||||
require('@backstage/cli/config/nodeTransform.cjs');
|
||||
require('../src');
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Knip report
|
||||
|
||||
## Unused devDependencies (3)
|
||||
## Unused devDependencies (2)
|
||||
|
||||
| Name | Location | Severity |
|
||||
| :-------------------- | :----------- | :------- |
|
||||
| @types/command-exists | package.json | error |
|
||||
| nodemon | package.json | error |
|
||||
| ts-node | package.json | error |
|
||||
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
"@types/node": "^18.17.8",
|
||||
"@types/recursive-readdir": "^2.2.0",
|
||||
"msw": "^1.0.0",
|
||||
"nodemon": "^3.0.1",
|
||||
"ts-node": "^10.0.0"
|
||||
"nodemon": "^3.0.1"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"watch": "./src",
|
||||
|
||||
@@ -51,6 +51,7 @@ jest.mock('./versions', () => ({
|
||||
root: '1.2.3',
|
||||
'@backstage/cli': '1.0.0',
|
||||
'@backstage/backend-common': '1.0.0',
|
||||
'@backstage/backend-defaults': '1.0.0',
|
||||
'@backstage/backend-tasks': '1.0.0',
|
||||
'@backstage/catalog-model': '1.0.0',
|
||||
'@backstage/catalog-client': '1.0.0',
|
||||
@@ -58,10 +59,14 @@ jest.mock('./versions', () => ({
|
||||
'@backstage/plugin-app-backend': '1.0.0',
|
||||
'@backstage/plugin-auth-backend': '1.0.0',
|
||||
'@backstage/plugin-auth-node': '1.0.0',
|
||||
'@backstage/plugin-auth-backend-module-github-provider': '1.0.0',
|
||||
'@backstage/plugin-auth-backend-module-guest-provider': '1.0.0',
|
||||
'@backstage/plugin-catalog-backend': '1.0.0',
|
||||
'@backstage/plugin-catalog-backend-module-scaffolder-entity-model': '1.0.0',
|
||||
'@backstage/plugin-permission-common': '1.0.0',
|
||||
'@backstage/plugin-permission-node': '1.0.0',
|
||||
'@backstage/plugin-permission-backend': '1.0.0',
|
||||
'@backstage/plugin-permission-backend-module-allow-all-policy': '1.0.0',
|
||||
'@backstage/plugin-proxy-backend': '1.0.0',
|
||||
'@backstage/plugin-scaffolder-backend': '1.0.0',
|
||||
'@backstage/plugin-search-backend': '1.0.0',
|
||||
|
||||
@@ -33,6 +33,7 @@ import { version as root } from '../../../../package.json';
|
||||
|
||||
import { version as appDefaults } from '../../../app-defaults/package.json';
|
||||
import { version as backendCommon } from '../../../backend-common/package.json';
|
||||
import { version as backendDefaults } from '../../../backend-defaults/package.json';
|
||||
import { version as backendTasks } from '../../../backend-tasks/package.json';
|
||||
import { version as catalogClient } from '../../../catalog-client/package.json';
|
||||
import { version as catalogModel } from '../../../catalog-model/package.json';
|
||||
@@ -50,6 +51,8 @@ import { version as theme } from '../../../theme/package.json';
|
||||
import { version as pluginApiDocs } from '../../../../plugins/api-docs/package.json';
|
||||
import { version as pluginAppBackend } from '../../../../plugins/app-backend/package.json';
|
||||
import { version as pluginAuthBackend } from '../../../../plugins/auth-backend/package.json';
|
||||
import { version as pluginAuthBackendModuleGithubProvider } from '../../../../plugins/auth-backend-module-github-provider/package.json';
|
||||
import { version as pluginAuthBackendModuleGuestProvider } from '../../../../plugins/auth-backend-module-guest-provider/package.json';
|
||||
import { version as pluginAuthNode } from '../../../../plugins/auth-node/package.json';
|
||||
import { version as pluginCatalog } from '../../../../plugins/catalog/package.json';
|
||||
import { version as pluginCatalogCommon } from '../../../../plugins/catalog-common/package.json';
|
||||
@@ -62,6 +65,8 @@ import { version as pluginExplore } from '../../../../plugins/explore/package.js
|
||||
import { version as pluginGithubActions } from '../../../../plugins/github-actions/package.json';
|
||||
import { version as pluginLighthouse } from '../../../../plugins/lighthouse/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';
|
||||
import { version as pluginPermissionCommon } from '../../../../plugins/permission-common/package.json';
|
||||
import { version as pluginPermissionReact } from '../../../../plugins/permission-react/package.json';
|
||||
import { version as pluginPermissionNode } from '../../../../plugins/permission-node/package.json';
|
||||
@@ -87,6 +92,7 @@ export const packageVersions = {
|
||||
root,
|
||||
'@backstage/app-defaults': appDefaults,
|
||||
'@backstage/backend-common': backendCommon,
|
||||
'@backstage/backend-defaults': backendDefaults,
|
||||
'@backstage/backend-tasks': backendTasks,
|
||||
'@backstage/catalog-client': catalogClient,
|
||||
'@backstage/catalog-model': catalogModel,
|
||||
@@ -101,6 +107,10 @@ export const packageVersions = {
|
||||
'@backstage/plugin-api-docs': pluginApiDocs,
|
||||
'@backstage/plugin-app-backend': pluginAppBackend,
|
||||
'@backstage/plugin-auth-backend': pluginAuthBackend,
|
||||
'@backstage/plugin-auth-backend-module-github-provider':
|
||||
pluginAuthBackendModuleGithubProvider,
|
||||
'@backstage/plugin-auth-backend-module-guest-provider':
|
||||
pluginAuthBackendModuleGuestProvider,
|
||||
'@backstage/plugin-auth-node': pluginAuthNode,
|
||||
'@backstage/plugin-catalog': pluginCatalog,
|
||||
'@backstage/plugin-catalog-common': pluginCatalogCommon,
|
||||
@@ -114,6 +124,9 @@ export const packageVersions = {
|
||||
'@backstage/plugin-github-actions': pluginGithubActions,
|
||||
'@backstage/plugin-lighthouse': pluginLighthouse,
|
||||
'@backstage/plugin-org': pluginOrg,
|
||||
'@backstage/plugin-permission-backend': pluginPermissionBackend,
|
||||
'@backstage/plugin-permission-backend-module-allow-all-policy':
|
||||
pluginPermissionBackendModulePolicyAllowAll,
|
||||
'@backstage/plugin-permission-common': pluginPermissionCommon,
|
||||
'@backstage/plugin-permission-node': pluginPermissionNode,
|
||||
'@backstage/plugin-permission-react': pluginPermissionReact,
|
||||
|
||||
@@ -28,6 +28,10 @@ backend:
|
||||
# ca: # if you have a CA file and want to verify it you can uncomment this section
|
||||
# $file: <file-path>/ca/server.crt
|
||||
|
||||
auth:
|
||||
providers:
|
||||
guest: null
|
||||
|
||||
catalog:
|
||||
# Overrides the default list locations from app-config.yaml as these contain example data.
|
||||
# See https://backstage.io/docs/features/software-catalog/#adding-components-to-the-catalog for more details
|
||||
|
||||
@@ -64,7 +64,9 @@ techdocs:
|
||||
|
||||
auth:
|
||||
# see https://backstage.io/docs/auth/ to learn about auth providers
|
||||
providers: {}
|
||||
providers:
|
||||
# See https://backstage.io/docs/auth/guest/provider
|
||||
guest: {}
|
||||
|
||||
scaffolder:
|
||||
# see https://backstage.io/docs/features/software-templates/configuration for software template options
|
||||
|
||||
@@ -19,5 +19,9 @@ import { test, expect } from '@playwright/test';
|
||||
test('App should render the welcome page', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const enterButton = page.getByRole('button', { name: 'Enter' });
|
||||
await expect(enterButton).toBeVisible();
|
||||
await enterButton.click();
|
||||
|
||||
await expect(page.getByText('My Company Catalog')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -27,7 +27,11 @@ import { entityPage } from './components/catalog/EntityPage';
|
||||
import { searchPage } from './components/search/SearchPage';
|
||||
import { Root } from './components/Root';
|
||||
|
||||
import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';
|
||||
import {
|
||||
AlertDisplay,
|
||||
OAuthRequestDialog,
|
||||
SignInPage,
|
||||
} from '@backstage/core-components';
|
||||
import { createApp } from '@backstage/app-defaults';
|
||||
import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
|
||||
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
|
||||
@@ -53,6 +57,9 @@ const app = createApp({
|
||||
catalogIndex: catalogPlugin.routes.catalogIndex,
|
||||
});
|
||||
},
|
||||
components: {
|
||||
SignInPage: props => <SignInPage {...props} auto providers={['guest']} />,
|
||||
},
|
||||
});
|
||||
|
||||
const routes = (
|
||||
|
||||
@@ -17,30 +17,30 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^{{version '@backstage/backend-common'}}",
|
||||
"@backstage/backend-defaults": "^{{version '@backstage/backend-defaults'}}",
|
||||
"@backstage/backend-tasks": "^{{version '@backstage/backend-tasks'}}",
|
||||
"@backstage/catalog-client": "^{{version '@backstage/catalog-client'}}",
|
||||
"@backstage/catalog-model": "^{{version '@backstage/catalog-model'}}",
|
||||
"@backstage/config": "^{{version '@backstage/config'}}",
|
||||
"@backstage/plugin-app-backend": "^{{version '@backstage/plugin-app-backend'}}",
|
||||
"@backstage/plugin-auth-backend": "^{{version '@backstage/plugin-auth-backend'}}",
|
||||
"@backstage/plugin-auth-backend-module-github-provider": "^{{version '@backstage/plugin-auth-backend-module-github-provider'}}",
|
||||
"@backstage/plugin-auth-backend-module-guest-provider": "^{{version '@backstage/plugin-auth-backend-module-guest-provider'}}",
|
||||
"@backstage/plugin-auth-node": "^{{version '@backstage/plugin-auth-node'}}",
|
||||
"@backstage/plugin-catalog-backend": "^{{version '@backstage/plugin-catalog-backend'}}",
|
||||
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^{{version '@backstage/plugin-catalog-backend-module-scaffolder-entity-model'}}",
|
||||
"@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'}}",
|
||||
"@backstage/plugin-permission-node": "^{{version '@backstage/plugin-permission-node'}}",
|
||||
"@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}",
|
||||
"@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}",
|
||||
"@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-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}",
|
||||
"app": "link:../app",
|
||||
"better-sqlite3": "^9.0.0",
|
||||
"dockerode": "^3.3.1",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"node-gyp": "^9.0.0",
|
||||
"pg": "^8.11.3",
|
||||
"winston": "^3.2.1"
|
||||
|
||||
@@ -6,110 +6,36 @@
|
||||
* Happy hacking!
|
||||
*/
|
||||
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
createServiceBuilder,
|
||||
loadBackendConfig,
|
||||
getRootLogger,
|
||||
useHotMemoize,
|
||||
notFoundHandler,
|
||||
CacheManager,
|
||||
DatabaseManager,
|
||||
HostDiscovery,
|
||||
UrlReaders,
|
||||
ServerTokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
import { Config } from '@backstage/config';
|
||||
import app from './plugins/app';
|
||||
import auth from './plugins/auth';
|
||||
import catalog from './plugins/catalog';
|
||||
import scaffolder from './plugins/scaffolder';
|
||||
import proxy from './plugins/proxy';
|
||||
import techdocs from './plugins/techdocs';
|
||||
import search from './plugins/search';
|
||||
import { PluginEnvironment } from './types';
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
|
||||
import { createBackend } from '@backstage/backend-defaults';
|
||||
|
||||
function makeCreateEnv(config: Config) {
|
||||
const root = getRootLogger();
|
||||
const reader = UrlReaders.default({ logger: root, config });
|
||||
const discovery = HostDiscovery.fromConfig(config);
|
||||
const cacheManager = CacheManager.fromConfig(config);
|
||||
const databaseManager = DatabaseManager.fromConfig(config, { logger: root });
|
||||
const tokenManager = ServerTokenManager.noop();
|
||||
const taskScheduler = TaskScheduler.fromConfig(config, { databaseManager });
|
||||
const backend = createBackend();
|
||||
|
||||
const identity = DefaultIdentityClient.create({
|
||||
discovery,
|
||||
});
|
||||
const permissions = ServerPermissionClient.fromConfig(config, {
|
||||
discovery,
|
||||
tokenManager,
|
||||
});
|
||||
backend.add(import('@backstage/plugin-app-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-proxy-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-scaffolder-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-techdocs-backend/alpha'));
|
||||
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
// auth plugin
|
||||
backend.add(import('@backstage/plugin-auth-backend'));
|
||||
// See https://backstage.io/docs/backend-system/building-backends/migrating#the-auth-plugin
|
||||
backend.add(import('@backstage/plugin-auth-backend-module-guest-provider'));
|
||||
// See https://github.com/backstage/backstage/blob/master/docs/auth/guest/provider.md
|
||||
|
||||
return (plugin: string): PluginEnvironment => {
|
||||
const logger = root.child({ type: 'plugin', plugin });
|
||||
const database = databaseManager.forPlugin(plugin);
|
||||
const cache = cacheManager.forPlugin(plugin);
|
||||
const scheduler = taskScheduler.forPlugin(plugin);
|
||||
return {
|
||||
logger,
|
||||
database,
|
||||
cache,
|
||||
config,
|
||||
reader,
|
||||
discovery,
|
||||
tokenManager,
|
||||
scheduler,
|
||||
permissions,
|
||||
identity,
|
||||
};
|
||||
};
|
||||
}
|
||||
// catalog plugin
|
||||
backend.add(import('@backstage/plugin-catalog-backend/alpha'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'),
|
||||
);
|
||||
|
||||
async function main() {
|
||||
const config = await loadBackendConfig({
|
||||
argv: process.argv,
|
||||
logger: getRootLogger(),
|
||||
});
|
||||
const createEnv = makeCreateEnv(config);
|
||||
// permission plugin
|
||||
backend.add(import('@backstage/plugin-permission-backend/alpha'));
|
||||
backend.add(
|
||||
import('@backstage/plugin-permission-backend-module-allow-all-policy'),
|
||||
);
|
||||
|
||||
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
|
||||
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
|
||||
const authEnv = useHotMemoize(module, () => createEnv('auth'));
|
||||
const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
|
||||
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
|
||||
const searchEnv = useHotMemoize(module, () => createEnv('search'));
|
||||
const appEnv = useHotMemoize(module, () => createEnv('app'));
|
||||
// search plugin
|
||||
backend.add(import('@backstage/plugin-search-backend/alpha'));
|
||||
backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha'));
|
||||
backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha'));
|
||||
|
||||
const apiRouter = Router();
|
||||
apiRouter.use('/catalog', await catalog(catalogEnv));
|
||||
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
|
||||
apiRouter.use('/auth', await auth(authEnv));
|
||||
apiRouter.use('/techdocs', await techdocs(techdocsEnv));
|
||||
apiRouter.use('/proxy', await proxy(proxyEnv));
|
||||
apiRouter.use('/search', await search(searchEnv));
|
||||
|
||||
// Add backends ABOVE this line; this 404 handler is the catch-all fallback
|
||||
apiRouter.use(notFoundHandler());
|
||||
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(config)
|
||||
.addRouter('/api', apiRouter)
|
||||
.addRouter('', await app(appEnv));
|
||||
|
||||
await service.start().catch(err => {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.hot?.accept();
|
||||
main().catch(error => {
|
||||
console.error('Backend failed to start up', error);
|
||||
process.exit(1);
|
||||
});
|
||||
backend.start();
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { createRouter } from '@backstage/plugin-app-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
appPackageName: 'app',
|
||||
});
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import {
|
||||
createRouter,
|
||||
providers,
|
||||
defaultAuthProviderFactories,
|
||||
} from '@backstage/plugin-auth-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
discovery: env.discovery,
|
||||
tokenManager: env.tokenManager,
|
||||
providerFactories: {
|
||||
...defaultAuthProviderFactories,
|
||||
|
||||
// This replaces the default GitHub auth provider with a customized one.
|
||||
// The `signIn` option enables sign-in for this provider, using the
|
||||
// identity resolution logic that's provided in the `resolver` callback.
|
||||
//
|
||||
// This particular resolver makes all users share a single "guest" identity.
|
||||
// It should only be used for testing and trying out Backstage.
|
||||
//
|
||||
// If you want to use a production ready resolver you can switch to
|
||||
// the one that is commented out below, it looks up a user entity in the
|
||||
// catalog using the GitHub username of the authenticated user.
|
||||
// That resolver requires you to have user entities populated in the catalog,
|
||||
// for example using https://backstage.io/docs/integrations/github/org
|
||||
//
|
||||
// There are other resolvers to choose from, and you can also create
|
||||
// your own, see the auth documentation for more details:
|
||||
//
|
||||
// https://backstage.io/docs/auth/identity-resolver
|
||||
github: providers.github.create({
|
||||
signIn: {
|
||||
resolver(_, ctx) {
|
||||
const userRef = 'user:default/guest'; // Must be a full entity reference
|
||||
return ctx.issueToken({
|
||||
claims: {
|
||||
sub: userRef, // The user's own identity
|
||||
ent: [userRef], // A list of identities that the user claims ownership through
|
||||
},
|
||||
});
|
||||
},
|
||||
// resolver: providers.github.resolvers.usernameMatchingUserEntityName(),
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
|
||||
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-catalog-backend-module-scaffolder-entity-model';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
builder.addProcessor(new ScaffolderEntitiesProcessor());
|
||||
const { processingEngine, router } = await builder.build();
|
||||
await processingEngine.start();
|
||||
return router;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { createRouter } from '@backstage/plugin-proxy-backend';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
return await createRouter({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
discovery: env.discovery,
|
||||
});
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user