This commit is contained in:
Yousif Al-Raheem
2021-11-25 10:05:03 +01:00
443 changed files with 5809 additions and 1917 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/errors': patch
---
Deprecate `parseErrorResponse` in favour of `parseErrorResponseBody`. Deprecate `data` field inside `ErrorResponse` in favour of `body`.
Rename the error name for unknown errors from `unknown` to `error`.
+2 -2
View File
@@ -23,13 +23,13 @@ const {
async function getDependencyReleaseLine(changesets, dependenciesUpdated) {
if (dependenciesUpdated.length === 0) return '';
const updatedDepenenciesList = dependenciesUpdated.map(
const updatedDependenciesList = dependenciesUpdated.map(
dependency => ` - ${dependency.name}@${dependency.newVersion}`,
);
// Return one `Updated dependencies` bullet instead of repeating for each changeset; this
// sacrifices the commit shas for brevity.
return ['- Updated dependencies', ...updatedDepenenciesList].join('\n');
return ['- Updated dependencies', ...updatedDependenciesList].join('\n');
}
module.exports = {
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/dev-utils': patch
---
Add theme switcher to sidebar of dev app.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Remove the "View Api" icon in the AboutCard, as the information is misleading for some users and is
duplicated in the tabs above.
-14
View File
@@ -1,14 +0,0 @@
---
'@backstage/config-loader': minor
---
Update `loadConfig` to return `LoadConfigResult` instead of an array of `AppConfig`.
This function is primarily used internally by other config loaders like `loadBackendConfig` which means no changes are required for most users.
If you use `loadConfig` directly you will need to update your usage from:
```diff
- const appConfigs = await loadConfig(options)
+ const { appConfigs } = await loadConfig(options)
```
@@ -1,5 +0,0 @@
---
'@backstage/plugin-cost-insights': patch
---
Fixed generation of sample data in the example Cost Insights client
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/catalog-client': patch
---
Update to the right version of @backstage/errors
-19
View File
@@ -1,19 +0,0 @@
---
'@backstage/plugin-gcp-projects': patch
---
UI updates to GCP-projects plugin
Adds the following to the project list page:
- pagination
- filtering
- sorting
- rows per page
- show/hide columns
Makes breadcrumb a link back to project list for the project details and new project views.
In project list page, updates New project button to use RouterLink instead of `href` to avoid login prompt.
In project details view, links to project details and logs now work, clicking on these will open the project or logs in GCP in new tab.
-8
View File
@@ -1,8 +0,0 @@
---
'@backstage/catalog-model': patch
'@backstage/cli': patch
'@backstage/config-loader': patch
'@backstage/plugin-scaffolder': patch
---
Update the json-schema dependency version.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
remove double config dep
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-kafka-backend': patch
---
Update Kafka configuration types
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Switch the default test coverage provider from the jest default one to `'v8'`, which provides much better coverage information when using the default Backstage test setup. This is considered a bug fix as the current coverage information is often very inaccurate.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/dev-utils': patch
---
Migrated to using `@backstage/app-defaults`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/backend-common': patch
---
Added the `isDatabaseConflictError` function.
-13
View File
@@ -1,13 +0,0 @@
---
'@backstage/create-app': patch
---
Migrated the app template use the new `@backstage/app-defaults` for the `createApp` import, since the `createApp` exported by `@backstage/app-core-api` will be removed in the future.
To migrate an existing application, add the latest version of `@backstage/app-defaults` as a dependency in `packages/app/package.json`, and make the following change to `packages/app/src/App.tsx`:
```diff
-import { createApp, FlatRoutes } from '@backstage/core-app-api';
+import { createApp } from '@backstage/app-defaults';
+import { FlatRoutes } from '@backstage/core-app-api';
```
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/backend-common': patch
'@backstage/cli': patch
---
Update internal usage of `configLoader.loadConfig` that now returns an object instead of an array of configs.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-user-settings': patch
---
Add Props Icon for Sidebar Item SidebarSearchField and Settings
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Disable ES transforms in tests transformed by the `jestSucraseTransform.js`. This is not considered a breaking change since all code is already transpiled this way in the development setup.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/create-app': patch
---
DefaultTechDocsCollator is now included in the search backend, and the Search Page updated with the SearchType component that includes the techdocs type
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-bazaar': patch
'@backstage/plugin-bazaar-backend': patch
---
A Bazaar project has been extended with the following fields: size, start date (optional), end date (optional) and a responsible person.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Changing the `Header` styles to use more theme variables. With this the title `font-size` will not change on resizing the window.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/create-app': patch
---
Refactor and add regression tests for create-app tasks
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': minor
---
Tweaked style insertion logic to make sure that JSS stylesheets always receive the highest priority.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/backend-common': patch
---
Paths can be specified in backend.reading.allow to further restrict allowed targets
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-app-api': patch
'@backstage/test-utils': patch
---
Migrated to using new `ErrorApiError` and `ErrorApiErrorContext` names.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-auth-backend': patch
---
Update OAuthAdapter to create identity.token from identity.idToken if it does not exist, and prevent overwrites to identity.toke. Update login page commonProvider to prefer .token over .idToken
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Skip empty file names when scaffolding with nunjucks
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
Adjust entity query construction to ensure sub-queries are always isolated from one another.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/backend-common': patch
---
Add `AbortSignal` support to `UrlReader`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-permission-common': minor
---
Accept configApi rather than enabled flag in PermissionClient constructor.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-app-api': patch
---
Deprecated the `BackstagePluginWithAnyOutput` type.
-12
View File
@@ -1,12 +0,0 @@
---
'@backstage/backend-common': patch
---
Make sure that server builder `start()` propagates errors (such as failing to bind to the required port) properly and doesn't resolve the promise prematurely.
After this change, the backend logger will be able to actually capture the error as it happens:
```
2021-11-11T10:54:21.334Z backstage info Initializing http server
2021-11-11T10:54:21.335Z backstage error listen EADDRINUSE: address already in use :::7000 code=EADDRINUSE errno=-48 syscall=listen address=:: port=7000
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-app-api': patch
---
Start exporting and marking several types as public to address errors in the API report.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-config-schema': patch
'@backstage/plugin-scaffolder': patch
---
Fixed a missing `await` when throwing server side errors
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-plugin-api': minor
---
Removed the unused `UserFlags` type.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-plugin-api': patch
---
Deprecated the `theme` property on `AppTheme`, replacing it with `Provider`. See https://backstage.io/docs/api/deprecations#app-theme for more details.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Added a scaffolder backend module template for the `create` command.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-plugin-api': minor
---
Remove exports of unused types(`RouteOptions` and `RoutePath`).
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/test-utils': patch
---
Migrated to using `createSpecializedApp`.
+42
View File
@@ -0,0 +1,42 @@
---
'@backstage/plugin-catalog-backend': minor
---
**BREAKING** EntitiesSearchFilter fields have changed.
EntitiesSearchFilter now has only two fields: `key` and `value`. The `matchValueIn` and `matchValueExists` fields are no longer are supported. Previous filters written using the `matchValueIn` and `matchValueExists` fields can be rewritten as follows:
Filtering by existence of key only:
```diff
filter: {
{
key: 'abc',
- matchValueExists: true,
},
}
```
Filtering by key and values:
```diff
filter: {
{
key: 'abc',
- matchValueExists: true,
- matchValueIn: ['xyz'],
+ values: ['xyz'],
},
}
```
Negation of filters can now be achieved through a `not` object:
```
filter: {
not: {
key: 'abc',
values: ['xyz'],
},
}
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Fixed a bug where calling `backstage-cli backend:bundle --build-dependencies` with no dependencies to be built would cause all monorepo packages to be built instead.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/backend-common': patch
---
Do not redact empty or one-character strings. These imply that it's just a test or local dev, and unnecessarily ruin the log output.
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/plugin-azure-devops': patch
'@backstage/plugin-azure-devops-backend': patch
'@backstage/plugin-azure-devops-common': minor
---
Improved Date handling for the Azure DevOps set of plugins by using strings and letting the frontend handle the conversion to DateTime
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Fixed entity triplet case handling for certain locales.
@@ -1,5 +0,0 @@
---
'@backstage/techdocs-common': patch
---
Added OpenStack Swift case migration support.
@@ -1,6 +0,0 @@
---
'@backstage/techdocs-common': patch
'@backstage/plugin-techdocs-backend': patch
---
Allow amazon web services s3 buckets to pass an server side encryption configuration so they can publish to encrypted buckets
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Use a better checkbox rendering in a task list.
@@ -1,5 +0,0 @@
---
'@backstage/plugin-techdocs': patch
---
Updates reader component used to display techdocs documentation. A previous change made this component not usable out of a page which don't have entityRef in url parameters. Reader component EntityRef parameter is now used instead of url parameters. Techdocs documentation component can now be used in our custom pages.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
bump `@rollup/plugin-commonjs` from 17.1.0 to 21.0.1
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/cli': patch
---
Introduces new `backstage-cli create` command to replace `create-plugin` and make space for creating a wider array of things. The create command also adds a new template for creating isomorphic common plugin packages.
-9
View File
@@ -1,9 +0,0 @@
---
'@backstage/core-app-api': patch
---
The `createApp` function from `@backstage/core-app-api` has been deprecated, with two new options being provided as a replacement.
The first and most commonly used one is `createApp` from the new `@backstage/app-defaults` package, which behaves just like the existing `createApp`. In the future this method is likely to be expanded to add more APIs and other pieces into the default setup, for example the Utility APIs from `@backstage/integration-react`.
The other option that we now provide is to use `createSpecializedApp` from `@backstage/core-app-api`. This is a more low-level API where you need to provide a full set of options, including your own `components`, `icons`, `defaultApis`, and `themes`. The `createSpecializedApp` way of creating an app is particularly useful if you are not using `@backstage/core-components` or MUI, as it allows you to avoid those dependencies completely.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
adds getDefaultProcessor method to CatalogBuilder
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Update the default routes to use id instead of title
+63
View File
@@ -0,0 +1,63 @@
---
'@backstage/core-app-api': patch
'@backstage/test-utils': patch
---
The `ApiRegistry` from `@backstage/core-app-api` class has been deprecated and will be removed in a future release. To replace it, we have introduced two new helpers that are exported from `@backstage/test-utils`, namely `TestApiProvider` and `TestApiRegistry`.
These two new helpers are more tailored for writing tests and development setups, as they allow for partial implementations of each of the APIs.
When migrating existing code it is typically best to prefer usage of `TestApiProvider` when possible, so for example the following code:
```tsx
render(
<ApiProvider
apis={ApiRegistry.from([
[identityApiRef, mockIdentityApi as unknown as IdentityApi]
])}
>
{...}
</ApiProvider>
)
```
Would be migrated to this:
```tsx
render(
<TestApiProvider apis={[[identityApiRef, mockIdentityApi]]}>
{...}
</TestApiProvider>
)
```
In cases where the `ApiProvider` is used in a more standalone way, for example to reuse a set of APIs across multiple tests, the `TestApiRegistry` can be used instead. Note that the `TestApiRegistry` only has a single static factory method, `.from()`, and it is slightly different from the existing `.from()` method on `ApiRegistry` in that it doesn't require the API pairs to be wrapped in an outer array.
Usage that looks like this:
```ts
const apis = ApiRegistry.with(
identityApiRef,
mockIdentityApi as unknown as IdentityApi,
).with(configApiRef, new ConfigReader({}));
```
OR like this:
```ts
const apis = ApiRegistry.from([
[identityApiRef, mockIdentityApi as unknown as IdentityApi],
[configApiRef, new ConfigReader({})],
]);
```
Would be migrated to this:
```ts
const apis = TestApiRegistry.from(
[identityApiRef, mockIdentityApi],
[configApiRef, new ConfigReader({})],
);
```
If your app is still using the `ApiRegistry` to construct the `apis` for `createApp`, we recommend that you move over to use the new method of supplying API factories instead, using `createApiFactory`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-plugin-api': patch
---
Deprecated the `Error` and `ErrorContext` types, replacing them with identical `ErrorApiError` and `ErrorApiErrorContext` types.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-components': patch
---
Pin sidebar by default for easier navigation
@@ -6,6 +6,8 @@ on:
jobs:
sync:
if: github.repository == 'backstage/backstage' # prevent running on forks
runs-on: ubuntu-latest
strategy:
+2
View File
@@ -69,3 +69,5 @@
| [Unity](https://unity.com) | [Ted Cordery](https://github.com/TeddyBallGame) | A centralized service catalog with documentation for our service engineers. |
| [PicPay](https://www.picpay.com) | [Luis Baroni](https://github.com/lcsbaroni), [Renata Poluceno](https://github.com/renatapoluceno), [PicPay](https://github.com/picpay) | Developer portal for building services throught templates, service catalog with ownership of services, documentation and metrics providing autonomy and visibility for all. |
| [Epic Games](https://www.epicgames.com) | [Brian Jung](https://github.com/brian-at-epic), [Jeff Goldian](https://github.com/jeffgoldian-Epic) | Developer Portal: Service Catalog, Documentation, Software Templates and more making our internal teams' lives easier! |
| [Globo](https://globo.com) | [Carlos Gusmão](https://github.com/caeugusmao), [Guilherme Vierno](https://github.com/vierno), [Denis Aoki](https://github.com/dnsaoki2), [Maycon Dionisio](https://github.com/MayconDionisio), | Reduce the friction of accessing the information engineers need about Globo's digital services through a coherent and centralized experience. |
| [QBE](https://www.qbe.com/) | [Daniel Steel](https://github.com/danielsteelqbe), [Pete Jespers](https://github.com/petejespersqbe) | Developer portal allowing our global teams to explore and create applications, documentation and cloud infrastructure easily and quickly 🚀 |
+3 -1
View File
@@ -122,7 +122,9 @@ We use [changesets](https://github.com/atlassian/changesets) to help us prepare
Any time a patch, minor, or major change aligning to [Semantic Versioning](https://semver.org) is made to any published package in `packages/` or `plugins/`, a changeset should be used. It helps to align your change to the [Backstage stability index](https://backstage.io/docs/overview/stability-index) for the package you are changing, for example, when to provide additional clarity on deprecation or impacting changes which will then be included into CHANGELOGs.
In general, changesets are not needed for the documentation, build utilities, contributed samples in `contrib/`, or the [example `packages/app`](packages/app).
In general, changesets are only needed for changes to packages within `packages/` or `plugins/` directories, and only for the packages that are not marked as `private`. Changesets are also not needed for changes that do not affect the published version of each package, for example changes to tests or in-line source code comments.
Changesets **are** needed for new packages, as that is what triggers the package to be part of the next release.
### How to create a changeset
@@ -8,6 +8,10 @@ If you're wanting to extend the functionality of the Scaffolder, you can do so
by writing custom actions which can be used along side our
[built-in actions](./builtin-actions.md).
> Note: When adding custom actions, the actions array will **replace the
> built-in actions too**. To ensure you can continue to include he builtin
> actions, see below to include them during registration of your action.
### Writing your Custom Action
Your custom action can live where you choose, but simplest is to include it
@@ -91,6 +95,8 @@ argument. It looks like the following:
- `createTemporaryDirectory` a function to call to give you a temporary
directory somewhere on the runner so you can store some files there rather
than polluting the `workspacePath`
- `ctx.metadata` - an object containing a `name` field, indicating the template
name. More metadata fields may be added later.
### Registering Custom Actions
@@ -113,22 +119,6 @@ return await createRouter({
There's another property you can pass here, which is an array of `actions` which
will set the available actions that the scaffolder has access to.
```ts
const actions = [createNewFileAction()];
return await createRouter({
containerRunner,
logger,
config,
database,
catalogClient,
reader,
actions,
});
```
**NOTE** - the actions array will replace the built-in actions too, so if you
want to have those as well as your new one, you'll need to do the following:
```ts
import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
import { ScmIntegrations } from '@backstage/integration';
@@ -144,7 +134,6 @@ const builtInActions = createBuiltinActions({
});
const actions = [...builtInActions, createNewFileAction()];
return await createRouter({
containerRunner,
logger,
@@ -284,8 +284,8 @@ to publish to. And it can be any host that is listed in your `integrations`
config in `app-config.yaml`.
The `RepoUrlPicker` is a custom field that we provide part of the
`plugin-scaffolder`. It's currently not possible to create your own fields yet,
but contributions are welcome! :)
`plugin-scaffolder`. You can provide your own custom fields by
[writing your own Custom Field Extensions](./writing-custom-field-extensions.md)
#### The Owner Picker
+1 -1
View File
@@ -2,5 +2,5 @@
"packages": ["packages/*", "plugins/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.1.0"
"version": "0.0.0"
}
@@ -1,5 +1,5 @@
---
title: Starting Phase 2: The Service Catalog
title: 'Starting Phase 2: The Service Catalog'
author: Stefan Ålund, Spotify
authorURL: http://twitter.com/stalund
authorImageURL: https://pbs.twimg.com/profile_images/121166861/6919c047c0d0edaace78c3009b28e917-user-full-200-130.generated_400x400.jpg
@@ -1,5 +1,5 @@
---
title: Announcing TechDocs: Spotifys docs-like-code plugin for Backstage
title: 'Announcing TechDocs: Spotifys docs-like-code plugin for Backstage'
author: Gary Niemen, Spotify
authorURL: https://github.com/garyniemen
---
@@ -1,5 +1,5 @@
---
title: New Cost Insights plugin: The engineers solution to taming cloud costs
title: 'New Cost Insights plugin: The engineers solution to taming cloud costs'
author: Janisa Anandamohan, Spotify
authorURL: https://twitter.com/janisa_a
---
@@ -1,5 +1,5 @@
---
title: New Backstage feature: Kubernetes for Service owners
title: 'New Backstage feature: Kubernetes for Service owners'
author: Matthew Clarke, Spotify
authorURL: https://github.com/mclarke47
---
@@ -1,5 +1,5 @@
---
title: Announcing the Backstage Search platform: a customizable search tool built just for you
title: 'Announcing the Backstage Search platform: a customizable search tool built just for you'
author: Emma Indal, Spotify
authorURL: https://www.linkedin.com/in/emma-indal
---
+2 -2
View File
@@ -1,7 +1,7 @@
---
title: Splunk On-Call
author: Spotify
authorUrl: https://github.com/spotify
author: ayshiff
authorUrl: https://github.com/ayshiff
category: Monitoring
description: Splunk On-Call offers a simple way to identify incidents and escalation policies.
documentation: https://github.com/backstage/backstage/tree/master/plugins/splunk-on-call
+27 -63
View File
@@ -1624,15 +1624,6 @@ cli-width@^2.0.0:
resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48"
integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==
clipboard@^2.0.0:
version "2.0.6"
resolved "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
clone-response@1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
@@ -1687,9 +1678,9 @@ color-name@^1.0.0, color-name@~1.1.4:
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.5.4:
version "1.5.4"
resolved "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6"
integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==
version "1.6.0"
resolved "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312"
integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
@@ -2158,11 +2149,6 @@ delayed-stream@~1.0.0:
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -3097,13 +3083,6 @@ globule@^1.0.0:
lodash "~4.17.10"
minimatch "~3.0.2"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
dependencies:
delegate "^3.1.2"
got@^7.0.0:
version "7.1.0"
resolved "https://registry.npmjs.org/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
@@ -3276,9 +3255,9 @@ highlight.js@^9.16.2:
integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
version "2.8.9"
resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hsl-regex@^1.0.0:
version "1.0.0"
@@ -4815,9 +4794,9 @@ path-key@^2.0.0, path-key@^2.0.1:
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
version "1.0.7"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-to-regexp@0.1.7:
version "0.1.7"
@@ -4850,6 +4829,11 @@ performance-now@^2.1.0:
resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
picocolors@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f"
integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -5189,13 +5173,12 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.23, postcss@^7.0.27, postcss@^7.0.32:
version "7.0.35"
resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
version "7.0.39"
resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309"
integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==
dependencies:
chalk "^2.4.2"
picocolors "^0.2.1"
source-map "^0.6.1"
supports-color "^6.1.0"
prepend-http@^1.0.1:
version "1.0.4"
@@ -5213,11 +5196,9 @@ prettier@^2.4.1:
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
prismjs@^1.22.0:
version "1.23.0"
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==
optionalDependencies:
clipboard "^2.0.0"
version "1.25.0"
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
process-nextick-args@~2.0.0:
version "2.0.1"
@@ -5709,11 +5690,6 @@ seek-bzip@^1.0.5:
dependencies:
commander "^2.8.1"
select@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
semver-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
@@ -5766,9 +5742,9 @@ serve-static@1.14.1:
send "0.17.1"
set-getter@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
integrity sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=
version "0.1.1"
resolved "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102"
integrity sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==
dependencies:
to-object-path "^0.3.0"
@@ -6150,13 +6126,6 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
supports-color@^6.1.0:
version "6.1.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
dependencies:
has-flag "^3.0.0"
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@@ -6250,11 +6219,6 @@ timsort@^0.3.0:
resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tiny-lr@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab"
@@ -6502,9 +6466,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0"
url-parse@^1.4.3:
version "1.4.7"
resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
version "1.5.3"
resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
+10
View File
@@ -0,0 +1,10 @@
# @backstage/app-defaults
## 0.1.1
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.7.4
- @backstage/core-plugin-api@0.2.0
- @backstage/core-app-api@0.1.21
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/app-defaults",
"description": "Provides the default wiring of a Backstage App",
"version": "0.1.0",
"version": "0.1.1",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,9 +29,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core-components": "^0.7.3",
"@backstage/core-app-api": "^0.1.20",
"@backstage/core-plugin-api": "^0.1.13",
"@backstage/core-components": "^0.7.4",
"@backstage/core-app-api": "^0.1.21",
"@backstage/core-plugin-api": "^0.2.0",
"@backstage/theme": "^0.2.13",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
@@ -39,8 +39,8 @@
"react-router-dom": "6.0.0-beta.0"
},
"devDependencies": {
"@backstage/cli": "^0.8.2",
"@backstage/test-utils": "^0.1.21",
"@backstage/cli": "^0.9.0",
"@backstage/test-utils": "^0.1.22",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@types/jest": "^26.0.7",
+45
View File
@@ -1,5 +1,50 @@
# example-app
## 0.2.53
### Patch Changes
- Updated dependencies
- @backstage/plugin-catalog@0.7.3
- @backstage/plugin-cost-insights@0.11.11
- @backstage/cli@0.9.0
- @backstage/plugin-gcp-projects@0.3.9
- @backstage/catalog-model@0.9.7
- @backstage/plugin-scaffolder@0.11.11
- @backstage/plugin-api-docs@0.6.14
- @backstage/plugin-azure-devops@0.1.4
- @backstage/plugin-badges@0.2.14
- @backstage/plugin-catalog-graph@0.2.2
- @backstage/plugin-catalog-import@0.7.4
- @backstage/plugin-catalog-react@0.6.4
- @backstage/plugin-circleci@0.2.29
- @backstage/plugin-cloudbuild@0.2.28
- @backstage/plugin-code-coverage@0.1.18
- @backstage/plugin-explore@0.3.21
- @backstage/plugin-github-actions@0.4.24
- @backstage/plugin-home@0.4.6
- @backstage/plugin-jenkins@0.5.12
- @backstage/plugin-kafka@0.2.21
- @backstage/plugin-kubernetes@0.4.20
- @backstage/plugin-lighthouse@0.2.30
- @backstage/plugin-newrelic@0.3.9
- @backstage/plugin-pagerduty@0.3.18
- @backstage/plugin-rollbar@0.3.19
- @backstage/plugin-search@0.4.18
- @backstage/plugin-sentry@0.3.29
- @backstage/plugin-tech-radar@0.4.12
- @backstage/plugin-techdocs@0.12.6
- @backstage/plugin-todo@0.1.15
- @backstage/plugin-user-settings@0.3.11
- @backstage/core-components@0.7.4
- @backstage/core-plugin-api@0.2.0
- @backstage/core-app-api@0.1.21
- @backstage/plugin-shortcuts@0.1.14
- @backstage/app-defaults@0.1.1
- @backstage/integration-react@0.1.14
- @backstage/plugin-graphiql@0.2.21
- @backstage/plugin-org@0.3.28
## 0.2.51
### Patch Changes
+41 -41
View File
@@ -1,48 +1,48 @@
{
"name": "example-app",
"version": "0.2.51",
"version": "0.2.53",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/app-defaults": "^0.1.0",
"@backstage/catalog-model": "^0.9.5",
"@backstage/cli": "^0.8.0",
"@backstage/core-app-api": "^0.1.18",
"@backstage/core-components": "^0.7.1",
"@backstage/core-plugin-api": "^0.1.11",
"@backstage/integration-react": "^0.1.12",
"@backstage/plugin-api-docs": "^0.6.12",
"@backstage/plugin-azure-devops": "^0.1.1",
"@backstage/plugin-badges": "^0.2.13",
"@backstage/plugin-catalog": "^0.7.2",
"@backstage/plugin-catalog-graph": "^0.2.1",
"@backstage/plugin-catalog-import": "^0.7.3",
"@backstage/plugin-catalog-react": "^0.6.1",
"@backstage/plugin-circleci": "^0.2.27",
"@backstage/plugin-cloudbuild": "^0.2.27",
"@backstage/plugin-code-coverage": "^0.1.15",
"@backstage/plugin-cost-insights": "^0.11.10",
"@backstage/plugin-explore": "^0.3.20",
"@backstage/plugin-gcp-projects": "^0.3.8",
"@backstage/plugin-github-actions": "^0.4.22",
"@backstage/plugin-graphiql": "^0.2.20",
"@backstage/plugin-home": "^0.4.4",
"@backstage/plugin-jenkins": "^0.5.11",
"@backstage/plugin-kafka": "^0.2.19",
"@backstage/plugin-kubernetes": "^0.4.17",
"@backstage/plugin-lighthouse": "^0.2.29",
"@backstage/plugin-newrelic": "^0.3.8",
"@backstage/plugin-org": "^0.3.27",
"@backstage/plugin-pagerduty": "0.3.17",
"@backstage/plugin-rollbar": "^0.3.18",
"@backstage/plugin-scaffolder": "^0.11.8",
"@backstage/plugin-search": "^0.4.15",
"@backstage/plugin-sentry": "^0.3.26",
"@backstage/plugin-shortcuts": "^0.1.12",
"@backstage/plugin-tech-radar": "^0.4.11",
"@backstage/plugin-techdocs": "^0.12.3",
"@backstage/plugin-todo": "^0.1.14",
"@backstage/plugin-user-settings": "^0.3.10",
"@backstage/app-defaults": "^0.1.1",
"@backstage/catalog-model": "^0.9.7",
"@backstage/cli": "^0.9.0",
"@backstage/core-app-api": "^0.1.21",
"@backstage/core-components": "^0.7.4",
"@backstage/core-plugin-api": "^0.2.0",
"@backstage/integration-react": "^0.1.14",
"@backstage/plugin-api-docs": "^0.6.14",
"@backstage/plugin-azure-devops": "^0.1.4",
"@backstage/plugin-badges": "^0.2.14",
"@backstage/plugin-catalog": "^0.7.3",
"@backstage/plugin-catalog-graph": "^0.2.2",
"@backstage/plugin-catalog-import": "^0.7.4",
"@backstage/plugin-catalog-react": "^0.6.4",
"@backstage/plugin-circleci": "^0.2.29",
"@backstage/plugin-cloudbuild": "^0.2.28",
"@backstage/plugin-code-coverage": "^0.1.18",
"@backstage/plugin-cost-insights": "^0.11.11",
"@backstage/plugin-explore": "^0.3.21",
"@backstage/plugin-gcp-projects": "^0.3.9",
"@backstage/plugin-github-actions": "^0.4.24",
"@backstage/plugin-graphiql": "^0.2.21",
"@backstage/plugin-home": "^0.4.6",
"@backstage/plugin-jenkins": "^0.5.12",
"@backstage/plugin-kafka": "^0.2.21",
"@backstage/plugin-kubernetes": "^0.4.20",
"@backstage/plugin-lighthouse": "^0.2.30",
"@backstage/plugin-newrelic": "^0.3.9",
"@backstage/plugin-org": "^0.3.28",
"@backstage/plugin-pagerduty": "0.3.18",
"@backstage/plugin-rollbar": "^0.3.19",
"@backstage/plugin-scaffolder": "^0.11.11",
"@backstage/plugin-search": "^0.4.18",
"@backstage/plugin-sentry": "^0.3.29",
"@backstage/plugin-shortcuts": "^0.1.14",
"@backstage/plugin-tech-radar": "^0.4.12",
"@backstage/plugin-techdocs": "^0.12.6",
"@backstage/plugin-todo": "^0.1.15",
"@backstage/plugin-user-settings": "^0.3.11",
"@backstage/search-common": "^0.2.0",
"@backstage/theme": "^0.2.11",
"@material-ui/core": "^4.12.2",
@@ -64,7 +64,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/test-utils": "^0.1.19",
"@backstage/test-utils": "^0.1.22",
"@rjsf/core": "^3.0.0",
"@testing-library/cypress": "^7.0.1",
"@testing-library/jest-dom": "^5.10.1",
@@ -35,6 +35,7 @@ import {
} from '@backstage/plugin-api-docs';
import {
EntityAzurePipelinesContent,
EntityAzurePullRequestsContent,
isAzureDevOpsAvailable,
} from '@backstage/plugin-azure-devops';
import { EntityBadgesDialog } from '@backstage/plugin-badges';
@@ -264,6 +265,18 @@ const errorsContent = (
</EntitySwitch>
);
const pullRequestsContent = (
<EntitySwitch>
<EntitySwitch.Case if={isAzureDevOpsAvailable}>
<EntityAzurePullRequestsContent defaultLimit={25} />
</EntitySwitch.Case>
<EntitySwitch.Case>
<EntityGithubPullRequestsContent />
</EntitySwitch.Case>
</EntitySwitch>
);
const overviewContent = (
<Grid container spacing={3} alignItems="stretch">
{entityWarningContent}
@@ -368,7 +381,7 @@ const serviceEntityPage = (
</EntityLayout.Route>
<EntityLayout.Route path="/pull-requests" title="Pull Requests">
<EntityGithubPullRequestsContent />
{pullRequestsContent}
</EntityLayout.Route>
<EntityLayout.Route path="/code-insights" title="Code Insights">
@@ -427,7 +440,7 @@ const websiteEntityPage = (
</EntityLayout.Route>
<EntityLayout.Route path="/pull-requests" title="Pull Requests">
<EntityGithubPullRequestsContent />
{pullRequestsContent}
</EntityLayout.Route>
<EntityLayout.Route path="/code-insights" title="Code Insights">
+24
View File
@@ -1,5 +1,29 @@
# @backstage/backend-common
## 0.9.10
### Patch Changes
- d7c1e0e34a: Added the `isDatabaseConflictError` function.
- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers`
- 1e99c73c75: Update internal usage of `configLoader.loadConfig` that now returns an object instead of an array of configs.
- 1daada3a06: Paths can be specified in backend.reading.allow to further restrict allowed targets
- 7ad9a07b27: Adding config prop `pluginDivisionMode` to allow plugins using the `pg` client to create their own management schemas in the db. This allows `pg` client plugins to work in separate schemas in the same db.
- 01f74aa878: Add `AbortSignal` support to `UrlReader`
- a8732a1200: Make sure that server builder `start()` propagates errors (such as failing to bind to the required port) properly and doesn't resolve the promise prematurely.
After this change, the backend logger will be able to actually capture the error as it happens:
```
2021-11-11T10:54:21.334Z backstage info Initializing http server
2021-11-11T10:54:21.335Z backstage error listen EADDRINUSE: address already in use :::7000 code=EADDRINUSE errno=-48 syscall=listen address=:: port=7000
```
- 26b5da1c1a: Do not redact empty or one-character strings. These imply that it's just a test or local dev, and unnecessarily ruin the log output.
- Updated dependencies
- @backstage/config-loader@0.8.0
- @backstage/cli-common@0.1.6
## 0.9.9
### Patch Changes
+13
View File
@@ -69,6 +69,19 @@ export interface Config {
* Defaults to true if unspecified.
*/
ensureExists?: boolean;
/**
* How plugins databases are managed/divided in the provided database instance.
*
* `database` -> Plugins are each given their own database to manage their schemas/tables.
*
* `schema` -> Plugins will be given their own schema (in the specified/default database)
* to manage their tables.
*
* NOTE: Currently only supported by the `pg` client.
*
* @default database
*/
pluginDivisionMode?: 'database' | 'schema';
/** Plugin specific database configuration and client override */
plugin?: {
[pluginId: string]: {
+7 -7
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.9.9",
"version": "0.9.10",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -29,9 +29,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/cli-common": "^0.1.5",
"@backstage/cli-common": "^0.1.6",
"@backstage/config": "^0.1.11",
"@backstage/config-loader": "^0.7.2",
"@backstage/config-loader": "^0.8.0",
"@backstage/errors": "^0.1.4",
"@backstage/integration": "^0.6.9",
"@backstage/types": "^0.1.1",
@@ -39,7 +39,7 @@
"@lerna/project": "^4.0.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
"@types/dockerode": "^3.2.1",
"@types/dockerode": "^3.3.0",
"@types/express": "^4.17.6",
"archiver": "^5.0.2",
"aws-sdk": "^2.840.0",
@@ -47,7 +47,7 @@
"concat-stream": "^2.0.0",
"cors": "^2.8.5",
"cross-fetch": "^3.0.6",
"dockerode": "^3.2.1",
"dockerode": "^3.3.1",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fs-extra": "9.1.0",
@@ -80,8 +80,8 @@
}
},
"devDependencies": {
"@backstage/cli": "^0.8.2",
"@backstage/test-utils": "^0.1.21",
"@backstage/cli": "^0.9.0",
"@backstage/test-utils": "^0.1.22",
"@types/archiver": "^5.1.0",
"@types/compression": "^1.7.0",
"@types/concat-stream": "^1.6.0",
@@ -15,13 +15,18 @@
*/
import { ConfigReader } from '@backstage/config';
import { omit } from 'lodash';
import { createDatabaseClient, ensureDatabaseExists } from './connection';
import {
createDatabaseClient,
ensureDatabaseExists,
ensureSchemaExists,
} from './connection';
import { DatabaseManager } from './DatabaseManager';
jest.mock('./connection', () => ({
...jest.requireActual('./connection'),
createDatabaseClient: jest.fn(),
ensureDatabaseExists: jest.fn(),
ensureSchemaExists: jest.fn(),
}));
describe('DatabaseManager', () => {
@@ -314,5 +319,191 @@ describe('DatabaseManager', () => {
expect.stringContaining('userdbname'),
);
});
it('plugin sets schema override for pg client', async () => {
const overrideConfig = {
backend: {
database: {
client: 'pg',
pluginDivisionMode: 'schema',
connection: {
host: 'localhost',
user: 'foo',
password: 'bar',
database: 'foodb',
},
},
},
};
const testManager = DatabaseManager.fromConfig(
new ConfigReader(overrideConfig),
);
const pluginId = 'schemaoverride';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [baseConfig, overrides] = mockCalls[0];
expect(baseConfig.get()).toMatchObject({
client: 'pg',
connection: config.backend.database.connection,
});
expect(overrides).toMatchObject({
searchPath: [pluginId],
});
});
it('plugin does not provide schema override for non pg client', async () => {
const testManager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
client: 'sqlite3',
pluginDivisionMode: 'schema',
connection: {
host: 'localhost',
user: 'foo',
password: 'bar',
database: 'foodb',
},
},
},
}),
);
const pluginId = 'any-plugin';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [baseConfig, overrides] = mockCalls[0];
expect(baseConfig.get()).toMatchObject({
client: 'sqlite3',
connection: config.backend.database.connection,
});
expect(overrides).not.toHaveProperty('searchPath');
});
it('plugin does not provide schema override if pluginDivisionMode is set to database', async () => {
const testManager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
client: 'pg',
pluginDivisionMode: 'database',
connection: 'some-file-path',
},
},
}),
);
const pluginId = 'any-plugin';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [_baseConfig, overrides] = mockCalls[0];
expect(overrides).not.toHaveProperty('searchPath');
});
it('plugin does not provide schema override if pluginDivisionMode is not set', async () => {
const testManager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
client: 'pg',
connection: {
host: 'localhost',
user: 'foo',
password: 'bar',
database: 'foodb',
},
},
},
}),
);
const pluginId = 'schemaoverride';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [_baseConfig, overrides] = mockCalls[0];
expect(overrides).not.toHaveProperty('searchPath');
});
it('pluginDivisionMode ensures that each plugin schema exists', async () => {
const testManager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
client: 'pg',
pluginDivisionMode: 'schema',
connection: {
host: 'localhost',
user: 'foo',
password: 'bar',
database: 'foodb',
},
},
},
}),
);
const pluginId = 'testdbname';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(ensureSchemaExists).mock.calls;
const [_, schemaName] = mockCalls[0];
expect(schemaName).toEqual('testdbname');
});
it('pluginDivisionMode allows connection overrides for plugins', async () => {
const testManager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: {
client: 'pg',
pluginDivisionMode: 'schema',
connection: {
host: 'localhost',
user: 'foo',
password: 'bar',
database: 'foodb',
},
plugin: {
testdbname: {
connection: {
database: 'database_name_overriden',
host: 'newhost',
},
},
},
},
},
}),
);
const pluginId = 'testdbname';
await testManager.forPlugin(pluginId).getClient();
const mockCalls = mocked(createDatabaseClient).mock.calls.splice(-1);
const [baseConfig, overrides] = mockCalls[0];
expect(baseConfig.get()).toMatchObject({
client: 'pg',
connection: {
database: 'database_name_overriden',
host: 'newhost',
user: 'foo',
password: 'bar',
},
});
expect(overrides).toHaveProperty('searchPath', ['testdbname']);
expect(overrides).toHaveProperty(
'connection.database',
'database_name_overriden',
);
});
});
});
@@ -19,12 +19,15 @@ import { omit } from 'lodash';
import { Config, ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import {
createDatabaseClient,
createNameOverride,
ensureDatabaseExists,
normalizeConnection,
createSchemaOverride,
ensureSchemaExists,
createDatabaseClient,
} from './connection';
import { PluginDatabaseManager } from './types';
import { mergeDatabaseConfig } from './config';
/**
* Provides a config lookup path for a plugin's config block.
@@ -80,14 +83,15 @@ export class DatabaseManager {
* Provides the canonical database name for a given plugin.
*
* This method provides the effective database name which is determined using global
* and plugin specific database config. If no explicit database name is configured,
* this method will provide a generated name which is the pluginId prefixed with
* 'backstage_plugin_'.
* and plugin specific database config. If no explicit database name is configured
* and `pluginDivisionMode` is not `schema`, this method will provide a generated name
* which is the pluginId prefixed with 'backstage_plugin_'. If `pluginDivisionMode` is
* `schema`, it will fallback to using the default database for the knex instance.
*
* @param pluginId Lookup the database name for given plugin
* @returns String representing the plugin's database name
*/
private getDatabaseName(pluginId: string): string {
private getDatabaseName(pluginId: string): string | undefined {
const connection = this.getConnectionConfig(pluginId);
if (this.getClientType(pluginId).client === 'sqlite3') {
@@ -96,11 +100,16 @@ export class DatabaseManager {
(connection as Knex.Sqlite3ConnectionConfig)?.filename ?? ':memory:'
);
}
const databaseName = (connection as Knex.ConnectionConfig)?.database;
// `pluginDivisionMode` as `schema` should use overridden databaseName if supplied or fallback to default knex database
if (this.getPluginDivisionModeConfig() === 'schema') {
return databaseName;
}
// all other supported databases should fallback to an auto-prefixed name
return (
(connection as Knex.ConnectionConfig)?.database ??
`${this.prefix}${pluginId}`
);
return databaseName ?? `${this.prefix}${pluginId}`;
}
/**
@@ -137,13 +146,18 @@ export class DatabaseManager {
);
}
private getPluginDivisionModeConfig(): string {
return this.config.getOptionalString('pluginDivisionMode') ?? 'database';
}
/**
* Provides a Knex connection plugin config by combining base and plugin config.
*
* This method provides a baseConfig for a plugin database connector. If the client type
* has not been overridden, the global connection config will be included with plugin
* specific config as the base. Values from the plugin connection take precedence over the
* base. Base database name is omitted for all supported databases excluding SQLite.
* base. Base database name is omitted for all supported databases excluding SQLite unless
* `pluginDivisionMode` is set to `schema`.
*/
private getConnectionConfig(
pluginId: string,
@@ -154,10 +168,13 @@ export class DatabaseManager {
this.config.get('connection'),
this.config.getString('client'),
);
// As databases cannot be shared, the `database` property from the base connection
// is omitted. SQLite3's `filename` property is an exception as this is used as a
// Databases cannot be shared unless the `pluginDivisionMode` is set to `schema`. The
// `database` property from the base connection is omitted unless `pluginDivisionMode`
// is set to `schema`. SQLite3's `filename` property is an exception as this is used as a
// directory elsewhere so we preserve `filename`.
baseConnection = omit(baseConnection, 'database');
if (this.getPluginDivisionModeConfig() !== 'schema') {
baseConnection = omit(baseConnection, 'database');
}
// get and normalize optional plugin specific database connection
const connection = normalizeConnection(
@@ -188,6 +205,16 @@ export class DatabaseManager {
};
}
/**
* Provides a partial Knex.Config database schema override for a given plugin.
*
* @param pluginId Target plugin to get database schema override
* @returns Partial Knex.Config with database schema override
*/
private getSchemaOverrides(pluginId: string): Knex.Config | undefined {
return createSchemaOverride(this.getClientType(pluginId).client, pluginId);
}
/**
* Provides a partial Knex.Config database name override for a given plugin.
*
@@ -195,10 +222,10 @@ export class DatabaseManager {
* @returns Partial Knex.Config with database name override
*/
private getDatabaseOverrides(pluginId: string): Knex.Config {
return createNameOverride(
this.getClientType(pluginId).client,
this.getDatabaseName(pluginId),
);
const databaseName = this.getDatabaseName(pluginId);
return databaseName
? createNameOverride(this.getClientType(pluginId).client, databaseName)
: {};
}
/**
@@ -212,8 +239,8 @@ export class DatabaseManager {
this.getConfigForPlugin(pluginId) as JsonObject,
);
if (this.getEnsureExistsConfig(pluginId)) {
const databaseName = this.getDatabaseName(pluginId);
const databaseName = this.getDatabaseName(pluginId);
if (databaseName && this.getEnsureExistsConfig(pluginId)) {
try {
await ensureDatabaseExists(pluginConfig, databaseName);
} catch (error) {
@@ -223,9 +250,24 @@ export class DatabaseManager {
}
}
return createDatabaseClient(
pluginConfig,
let schemaOverrides;
if (this.getPluginDivisionModeConfig() === 'schema') {
try {
schemaOverrides = this.getSchemaOverrides(pluginId);
await ensureSchemaExists(pluginConfig, pluginId);
} catch (error) {
throw new Error(
`Failed to connect to the database to make sure that schema for plugin '${pluginId}' exists, ${error}`,
);
}
}
const databaseClientOverrides = mergeDatabaseConfig(
{},
this.getDatabaseOverrides(pluginId),
schemaOverrides,
);
return createDatabaseClient(pluginConfig, databaseClientOverrides);
}
}
@@ -18,8 +18,24 @@ import { ConfigReader } from '@backstage/config';
import {
createDatabaseClient,
createNameOverride,
createSchemaOverride,
ensureSchemaExists,
parseConnectionString,
} from './connection';
import { pgConnector } from './connectors';
const mocked = (f: Function) => f as jest.Mock;
jest.mock('./connectors', () => {
const connectors = jest.requireActual('./connectors');
return {
...connectors,
pgConnector: {
...connectors.pgConnector,
ensureSchemaExists: jest.fn(),
},
};
});
describe('database connection', () => {
describe('createDatabaseClient', () => {
@@ -152,4 +168,63 @@ describe('database connection', () => {
expect(() => parseConnectionString('sqlite://')).toThrow();
});
});
describe('createSchemaOverride', () => {
it('returns Knex config for postgres', () => {
expect(createSchemaOverride('pg', 'testpg')).toHaveProperty(
'searchPath',
['testpg'],
);
});
it('throws error for sqlite', () => {
expect(createSchemaOverride('sqlite3', 'testsqlite')).toBeUndefined();
});
it('returns Knex config for mysql', () => {
expect(createSchemaOverride('mysql', 'testmysql')).toBeUndefined();
});
it('throws an error for unknown connection', () => {
expect(createSchemaOverride('unknown', 'testname')).toBeUndefined();
});
});
describe('ensureSchemaExists', () => {
it('returns sucessfully with pg client', async () => {
await ensureSchemaExists(
new ConfigReader({
client: 'pg',
schema: 'catalog',
connection: 'postgresql://testuser:testpass@acme:5432/userdbname',
}),
'catalog',
);
const mockCalls = mocked(
pgConnector.ensureSchemaExists as Function,
).mock.calls.splice(-1);
const [baseConfig, schemaName] = mockCalls[0];
expect(baseConfig.get()).toMatchObject({
client: 'pg',
connection: 'postgresql://testuser:testpass@acme:5432/userdbname',
});
expect(schemaName).toEqual('catalog');
});
it('throws error for non pg client', () => {
return expect(
ensureSchemaExists(
new ConfigReader({
client: 'sqlite3',
schema: 'catalog',
connection: ':memory:',
}),
'catalog',
),
).resolves.toBeUndefined();
});
});
});
@@ -82,6 +82,23 @@ export async function ensureDatabaseExists(
);
}
/**
* Ensures that the given schemas all exist, creating them if they do not.
*
* @public
*/
export async function ensureSchemaExists(
dbConfig: Config,
...schemas: Array<string>
): Promise<void> {
const client: DatabaseClient = dbConfig.getString('client');
return await ConnectorMapping[client]?.ensureSchemaExists?.(
dbConfig,
...schemas,
);
}
/**
* Provides a Knex.Config object with the provided database name for a given client.
*/
@@ -99,6 +116,23 @@ export function createNameOverride(
}
}
/**
* Provides a Knex.Config object with the provided database schema for a given client. Currently only supported by `pg`.
*/
export function createSchemaOverride(
client: string,
name: string,
): Partial<Knex.Config | undefined> {
try {
return ConnectorMapping[client]?.createSchemaOverride?.(name);
} catch (e) {
throw new InputError(
`Unable to create database schema override for '${client}' connector`,
e,
);
}
}
/**
* Parses a connection string for a given client and provides a connection config.
*/
@@ -0,0 +1,25 @@
/*
* Copyright 2021 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.
*/
import defaultSchemaOverride from './defaultSchemaOverride';
describe('defaultNameOverride()', () => {
it('returns a partial knex static connection config with searchPath set to [schemaName]', () => {
const schemaName = 'schemaName';
expect(defaultSchemaOverride(schemaName)).toHaveProperty('searchPath', [
schemaName,
]);
});
});
@@ -0,0 +1,29 @@
/*
* Copyright 2021 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.
*/
import { Knex } from 'knex';
/**
* Provides a partial knex config with schema name override.
*
* @param name schema name to get config override for
*/
export default function defaultSchemaOverride(
name: string,
): Partial<Knex.Config> {
return {
searchPath: [name],
};
}
@@ -76,6 +76,24 @@ describe('postgres', () => {
});
});
it('overrides the schema name', () => {
const mockConnection = {
...createMockConnection(),
schema: 'schemaName',
};
expect(
buildPgDatabaseConfig(createConfig(mockConnection), {
searchPath: ['schemaName'],
}),
).toEqual({
client: 'pg',
connection: mockConnection,
searchPath: ['schemaName'],
useNullAsDefault: true,
});
});
it('adds additional config settings', () => {
const mockConnection = createMockConnection();
@@ -21,6 +21,7 @@ import { ForwardedError } from '@backstage/errors';
import { mergeDatabaseConfig } from '../config';
import { DatabaseConnector } from '../types';
import defaultNameOverride from './defaultNameOverride';
import defaultSchemaOverride from './defaultSchemaOverride';
/**
* Creates a knex postgres database connection
@@ -135,6 +136,29 @@ export async function ensurePgDatabaseExists(
}
}
/**
* Creates the missing Postgres schema if it does not exist
*
* @param dbConfig The database config
* @param schemas The name of the schemas to create
*/
export async function ensurePgSchemaExists(
dbConfig: Config,
...schemas: Array<string>
): Promise<void> {
const admin = createPgDatabaseClient(dbConfig);
try {
const ensureSchema = async (database: string) => {
await admin.raw(`CREATE SCHEMA IF NOT EXISTS ??`, [database]);
};
await Promise.all(schemas.map(ensureSchema));
} finally {
await admin.destroy();
}
}
/**
* PostgreSQL database connector.
*
@@ -143,6 +167,8 @@ export async function ensurePgDatabaseExists(
export const pgConnector: DatabaseConnector = Object.freeze({
createClient: createPgDatabaseClient,
ensureDatabaseExists: ensurePgDatabaseExists,
ensureSchemaExists: ensurePgSchemaExists,
createNameOverride: defaultNameOverride,
createSchemaOverride: defaultSchemaOverride,
parseConnectionString: parsePgConnectionString,
});
@@ -45,6 +45,11 @@ export interface DatabaseConnector {
* database name.
*/
createNameOverride(name: string): Partial<Knex.Config>;
/**
* createSchemaOverride provides a partial knex config sufficient to override a
* PostgreSQL schema name within utilizing the `searchPath` knex configuration.
*/
createSchemaOverride?(name: string): Partial<Knex.Config>;
/**
* parseConnectionString produces a knex connection config object representing
* a database connection string.
@@ -64,4 +69,16 @@ export interface DatabaseConnector {
dbConfig: Config,
...databases: Array<string>
): Promise<void>;
/**
* ensureSchemaExists performs a side-effect to ensure schema names passed in are
* present.
*
* Calling this function on schemas which already exist should do nothing.
* Missing schemas should be created if needed.
*/
ensureSchemaExists?(
dbConfig: Config,
...schemas: Array<string>
): Promise<void>;
}
+3 -3
View File
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.9.8",
"@backstage/backend-common": "^0.9.10",
"@backstage/config": "^0.1.11",
"@backstage/errors": "^0.1.4",
"@backstage/types": "^0.1.1",
@@ -43,8 +43,8 @@
"zod": "^3.9.5"
},
"devDependencies": {
"@backstage/backend-test-utils": "^0.1.8",
"@backstage/cli": "^0.8.1",
"@backstage/backend-test-utils": "^0.1.9",
"@backstage/cli": "^0.9.0",
"jest": "^26.0.1",
"wait-for-expect": "^3.0.2"
},
+9
View File
@@ -1,5 +1,14 @@
# @backstage/backend-test-utils
## 0.1.9
### Patch Changes
- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers`
- Updated dependencies
- @backstage/cli@0.9.0
- @backstage/backend-common@0.9.10
## 0.1.8
### Patch Changes
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
"version": "0.1.8",
"version": "0.1.9",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,18 +30,18 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.9.7",
"@backstage/cli": "^0.8.0",
"@backstage/backend-common": "^0.9.10",
"@backstage/cli": "^0.9.0",
"@backstage/config": "^0.1.9",
"knex": "^0.95.1",
"mysql2": "^2.2.5",
"pg": "^8.3.0",
"sqlite3": "^5.0.1",
"testcontainers": "^7.10.0",
"testcontainers": "^7.23.0",
"uuid": "^8.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.8.0",
"@backstage/cli": "^0.9.0",
"jest": "^26.0.1"
},
"files": [
+15 -15
View File
@@ -24,39 +24,39 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.9.9",
"@backstage/catalog-client": "^0.5.1",
"@backstage/catalog-model": "^0.9.5",
"@backstage/backend-common": "^0.9.10",
"@backstage/catalog-client": "^0.5.2",
"@backstage/catalog-model": "^0.9.7",
"@backstage/config": "^0.1.10",
"@backstage/integration": "^0.6.8",
"@backstage/plugin-app-backend": "^0.3.17",
"@backstage/plugin-auth-backend": "^0.4.7",
"@backstage/plugin-azure-devops-backend": "^0.2.0",
"@backstage/plugin-app-backend": "^0.3.19",
"@backstage/plugin-auth-backend": "^0.4.8",
"@backstage/plugin-azure-devops-backend": "^0.2.1",
"@backstage/plugin-badges-backend": "^0.1.11",
"@backstage/plugin-catalog-backend": "^0.17.3",
"@backstage/plugin-catalog-backend": "^0.17.4",
"@backstage/plugin-code-coverage-backend": "^0.1.14",
"@backstage/plugin-graphql-backend": "^0.1.9",
"@backstage/plugin-jenkins-backend": "^0.1.7",
"@backstage/plugin-kubernetes-backend": "^0.3.18",
"@backstage/plugin-kafka-backend": "^0.2.10",
"@backstage/plugin-kafka-backend": "^0.2.11",
"@backstage/plugin-proxy-backend": "^0.2.13",
"@backstage/plugin-rollbar-backend": "^0.1.15",
"@backstage/plugin-scaffolder-backend": "^0.15.12",
"@backstage/plugin-scaffolder-backend": "^0.15.13",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.7",
"@backstage/plugin-search-backend": "^0.2.6",
"@backstage/plugin-search-backend-node": "^0.4.2",
"@backstage/plugin-search-backend-module-elasticsearch": "^0.0.5",
"@backstage/plugin-search-backend-module-pg": "^0.2.1",
"@backstage/plugin-techdocs-backend": "^0.10.5",
"@backstage/plugin-tech-insights-backend": "^0.1.0",
"@backstage/plugin-techdocs-backend": "^0.10.8",
"@backstage/plugin-tech-insights-backend": "^0.1.1",
"@backstage/plugin-tech-insights-node": "^0.1.0",
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.0",
"@backstage/plugin-todo-backend": "^0.1.13",
"@gitbeaker/node": "^30.2.0",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^11.0.1",
"dockerode": "^3.2.1",
"example-app": "^0.2.51",
"dockerode": "^3.3.1",
"example-app": "^0.2.53",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"express-prom-bundle": "^6.3.6",
@@ -68,8 +68,8 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.8.2",
"@types/dockerode": "^3.2.1",
"@backstage/cli": "^0.9.0",
"@types/dockerode": "^3.3.0",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5"
},
+32 -40
View File
@@ -17,10 +17,12 @@ import {
createRouter,
buildTechInsightsContext,
createFactRetrieverRegistration,
entityOwnershipFactRetriever,
entityMetadataFactRetriever,
techdocsFactRetriever,
} from '@backstage/plugin-tech-insights-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { CatalogClient } from '@backstage/catalog-client';
import {
JsonRulesEngineFactCheckerFactory,
JSON_RULE_ENGINE_CHECK_TYPE,
@@ -38,41 +40,12 @@ export default async function createPlugin({
database,
discovery,
factRetrievers: [
createFactRetrieverRegistration('5 4 * * 6', {
// Example cron, At 04:05 on Saturday.
id: 'testRetriever',
version: '1.1.2',
entityFilter: [{ kind: 'component' }], // EntityFilter to be used in the future (creating checks, graphs etc.) to figure out which entities this fact retrieves data for.
schema: {
examplenumberfact: {
type: 'integer',
description: 'Example fact returning a number',
},
},
handler: async _ctx => {
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
const entities = await catalogClient.getEntities({
filter: [{ kind: 'component' }],
});
return Promise.resolve(
entities.items.map(it => {
return {
entity: {
namespace: it.metadata.namespace!!,
kind: it.kind,
name: it.metadata.name,
},
facts: {
examplenumberfact: 2,
},
};
}),
);
},
}),
createFactRetrieverRegistration(
'* * * * *', // Example cron, every minute
entityOwnershipFactRetriever,
),
createFactRetrieverRegistration('* * * * *', entityMetadataFactRetriever),
createFactRetrieverRegistration('* * * * *', techdocsFactRetriever),
],
factCheckerFactory: new JsonRulesEngineFactCheckerFactory({
checks: [
@@ -81,14 +54,33 @@ export default async function createPlugin({
type: JSON_RULE_ENGINE_CHECK_TYPE,
name: 'simpleTestCheck',
description: 'Simple Check For Testing',
factIds: ['testRetriever'],
factIds: [
'entityMetadataFactRetriever',
'techdocsFactRetriever',
'entityOwnershipFactRetriever',
],
rule: {
conditions: {
all: [
{
fact: 'examplenumberfact',
operator: 'lessThan',
value: 5,
fact: 'hasGroupOwner',
operator: 'equal',
value: true,
},
{
fact: 'hasTitle',
operator: 'equal',
value: true,
},
{
fact: 'hasDescription',
operator: 'equal',
value: true,
},
{
fact: 'hasAnnotationBackstageIoTechdocsRef',
operator: 'equal',
value: true,
},
],
},
+8
View File
@@ -1,5 +1,13 @@
# @backstage/catalog-client
## 0.5.2
### Patch Changes
- 3bf2238187: Update to the right version of @backstage/errors
- Updated dependencies
- @backstage/catalog-model@0.9.7
## 0.5.1
### Patch Changes
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-client",
"description": "An isomorphic client for the catalog backend",
"version": "0.5.1",
"version": "0.5.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,12 +30,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.9.5",
"@backstage/catalog-model": "^0.9.7",
"@backstage/errors": "^0.1.4",
"cross-fetch": "^3.0.6"
},
"devDependencies": {
"@backstage/cli": "^0.8.2",
"@backstage/cli": "^0.9.0",
"@types/jest": "^26.0.7",
"msw": "^0.35.0"
},
+6
View File
@@ -1,5 +1,11 @@
# @backstage/catalog-model
## 0.9.7
### Patch Changes
- 8809b6c0dd: Update the json-schema dependency version.
## 0.9.6
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/catalog-model",
"description": "Types and validators that help describe the model of a Backstage Catalog",
"version": "0.9.6",
"version": "0.9.7",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -42,7 +42,7 @@
"yup": "^0.32.9"
},
"devDependencies": {
"@backstage/cli": "^0.8.1",
"@backstage/cli": "^0.9.0",
"@types/jest": "^26.0.7",
"@types/lodash": "^4.14.151",
"yaml": "^1.9.2"
+8
View File
@@ -1,5 +1,13 @@
# @backstage/cli-common
## 0.1.6
### Patch Changes
- 677bfc2dd0: Keep backstage.json in sync
The `versions:bump` script now takes care about updating the `version` property inside `backstage.json` file. The file is created if is not present.
## 0.1.5
### Patch Changes
+3
View File
@@ -3,6 +3,9 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
// @public
export const BACKSTAGE_JSON = 'backstage.json';
// @public
export function findPaths(searchDir: string): Paths;
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli-common",
"description": "Common functionality used by cli, backend, and create-app",
"version": "0.1.5",
"version": "0.1.6",
"private": false,
"main": "src/index.ts",
"types": "src/index.ts",
+1 -1
View File
@@ -20,6 +20,6 @@
* @packageDocumentation
*/
export { findPaths } from './paths';
export { findPaths, BACKSTAGE_JSON } from './paths';
export { isChildPath } from './isChildPath';
export type { Paths, ResolveFunc } from './paths';
+7
View File
@@ -167,3 +167,10 @@ export function findPaths(searchDir: string): Paths {
resolveTargetRoot: (...paths) => resolvePath(getTargetRoot(), ...paths),
};
}
/**
* The name of the backstage's config file
*
* @public
*/
export const BACKSTAGE_JSON = 'backstage.json';

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