diff --git a/.changeset/afraid-shirts-train.md b/.changeset/afraid-shirts-train.md deleted file mode 100644 index bd83716dc4..0000000000 --- a/.changeset/afraid-shirts-train.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-tech-insights': patch ---- - -Added the possibility to customize the check description in the scorecard component. - -- The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. - -Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. -As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details diff --git a/.changeset/backend-like-a-tattoo.md b/.changeset/backend-like-a-tattoo.md deleted file mode 100644 index 0d2edfa7a9..0000000000 --- a/.changeset/backend-like-a-tattoo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Added `POSTGRES_11` and `POSTGRES_12` as supported test database IDs. diff --git a/.changeset/beige-tigers-matter.md b/.changeset/beige-tigers-matter.md deleted file mode 100644 index 248ce1fbf9..0000000000 --- a/.changeset/beige-tigers-matter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Fix case GitLab workspace is a nested subgroup diff --git a/.changeset/brown-eyes-yell.md b/.changeset/brown-eyes-yell.md deleted file mode 100644 index 5ed4140bba..0000000000 --- a/.changeset/brown-eyes-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-pull-requests-board': patch ---- - -The `EntityTeamPullRequestsContent` and `EntityTeamPullRequestsCard` support the ability to view the labels/tags added to each PR diff --git a/.changeset/calm-snails-trade.md b/.changeset/calm-snails-trade.md deleted file mode 100644 index 0738b5aa37..0000000000 --- a/.changeset/calm-snails-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-bazaar': patch ---- - -Fixed `validateDOMNesting` warnings diff --git a/.changeset/calm-wolves-taste.md b/.changeset/calm-wolves-taste.md deleted file mode 100644 index ec0a7fb4f0..0000000000 --- a/.changeset/calm-wolves-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Fixed 404 Error when fetching search results due to URL encoding changes diff --git a/.changeset/chatty-ads-attack.md b/.changeset/chatty-ads-attack.md new file mode 100644 index 0000000000..709db946dd --- /dev/null +++ b/.changeset/chatty-ads-attack.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +fixed refresh problem when backstage backend disconnects without any feedback to user. Now we send a generic message and try to reconnect after 15 seconds diff --git a/.changeset/chilled-pants-wonder.md b/.changeset/chilled-pants-wonder.md deleted file mode 100644 index 501ced7cba..0000000000 --- a/.changeset/chilled-pants-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-openapi-utils': patch ---- - -Use permalinks for links including a line number reference diff --git a/.changeset/chilled-queens-wonder.md b/.changeset/chilled-queens-wonder.md deleted file mode 100644 index a10212792d..0000000000 --- a/.changeset/chilled-queens-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Ensure that entity cache state is only written to the database when actually changed diff --git a/.changeset/chilly-fireants-type.md b/.changeset/chilly-fireants-type.md deleted file mode 100644 index 6bff750d57..0000000000 --- a/.changeset/chilly-fireants-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Remove the direct dependency on deprecated "request" library diff --git a/.changeset/clean-lobsters-brake.md b/.changeset/clean-lobsters-brake.md deleted file mode 100644 index f6da6e986e..0000000000 --- a/.changeset/clean-lobsters-brake.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': minor ---- - -Allow fetching pod metrics limited by a `labelSelector`. - -This is used by the Kubernetes tab on a components' page and leads to much smaller responses being received from Kubernetes, especially with larger Kubernetes clusters. diff --git a/.changeset/cold-drinks-exercise.md b/.changeset/cold-drinks-exercise.md deleted file mode 100644 index e47e133929..0000000000 --- a/.changeset/cold-drinks-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': patch ---- - -Make sure that the first support button row does not break across lines diff --git a/.changeset/create-app-1682437922.md b/.changeset/create-app-1682437922.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1682437922.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/curvy-months-appear.md b/.changeset/curvy-months-appear.md deleted file mode 100644 index 487e60c437..0000000000 --- a/.changeset/curvy-months-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Re-add the possibility to have trailing slashes in Techdocs navigation. diff --git a/.changeset/curvy-years-smoke.md b/.changeset/curvy-years-smoke.md new file mode 100644 index 0000000000..056056fdff --- /dev/null +++ b/.changeset/curvy-years-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Forward `Authorization` header for `EventSource` when credentials are available. diff --git a/.changeset/dry-boats-sniff.md b/.changeset/dry-boats-sniff.md deleted file mode 100644 index 0c359b5536..0000000000 --- a/.changeset/dry-boats-sniff.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/app-defaults': patch ---- - -Added a System Icon for resource entities. -This can be obtained using: - -```ts -useApp().getSystemIcon('kind:resource'); -``` diff --git a/.changeset/dull-wombats-stare.md b/.changeset/dull-wombats-stare.md deleted file mode 100644 index 36ba412c02..0000000000 --- a/.changeset/dull-wombats-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-openapi-utils': patch ---- - -Adjusted README accordingly after the generated output now has a `.generated.ts` extension diff --git a/.changeset/eighty-olives-live.md b/.changeset/eighty-olives-live.md deleted file mode 100644 index 16898701f4..0000000000 --- a/.changeset/eighty-olives-live.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Updated the `DatabaseManager` to include the plugin id in the Postgres application name of the database connections created for each plugin. diff --git a/.changeset/extragavent-fast-fly.md b/.changeset/extragavent-fast-fly.md deleted file mode 100644 index bba3d8a9c3..0000000000 --- a/.changeset/extragavent-fast-fly.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-badges': patch -'@backstage/plugin-badges-backend': minor ---- - -Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. - -Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. - -**BREAKING**: `createRouter` now require that `tokenManager`, `logger`, `identityApi` and `database`, are passed in as options. diff --git a/.changeset/fifty-grapes-explode.md b/.changeset/fifty-grapes-explode.md deleted file mode 100644 index 999a105c4f..0000000000 --- a/.changeset/fifty-grapes-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed a bug in the `queryEntities` endpoint that was causing filtered entities to be included in cursor requests. diff --git a/.changeset/fifty-laws-count.md b/.changeset/fifty-laws-count.md deleted file mode 100644 index f20e41fc20..0000000000 --- a/.changeset/fifty-laws-count.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch ---- - -Omit managed fields in the Kubernetes resource YAML display. diff --git a/.changeset/five-tigers-whisper.md b/.changeset/five-tigers-whisper.md deleted file mode 100644 index aa9758c3b5..0000000000 --- a/.changeset/five-tigers-whisper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-stack-overflow': patch ---- - -StackOverflowSearchResultListItem can now accept an empty result prop so that it can be rendered in the suggested SearchResultListItem pattern. diff --git a/.changeset/fresh-moons-unite.md b/.changeset/fresh-moons-unite.md deleted file mode 100644 index 3d3af7e698..0000000000 --- a/.changeset/fresh-moons-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Adjusted the OpenAPI schema file name according to the new structure diff --git a/.changeset/funny-trains-sniff.md b/.changeset/funny-trains-sniff.md deleted file mode 100644 index 91dbd28c28..0000000000 --- a/.changeset/funny-trains-sniff.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor -'@backstage/plugin-catalog': minor ---- - -Added an entity namespace filter and column on the default catalog page. - -If you have a custom version of the catalog page, you can add this filter in your CatalogPage code: - -```ts - - - - - - /* if you want namespace picker */ - - - - - - -``` - -The namespace column can be added using `createNamespaceColumn();`. This is only needed if you customized the columns for CatalogTable. diff --git a/.changeset/good-lions-approve.md b/.changeset/good-lions-approve.md deleted file mode 100644 index f4065a6ab3..0000000000 --- a/.changeset/good-lions-approve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Fixed a bug where the wrong credentials would be selected when using multiple GitHub app integrations. diff --git a/.changeset/green-cheetahs-cover.md b/.changeset/green-cheetahs-cover.md deleted file mode 100644 index 2633a5af01..0000000000 --- a/.changeset/green-cheetahs-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': minor ---- - -The analytics' `navigate` event will now include the route parameters as attributes of the navigate event diff --git a/.changeset/healthy-ladybugs-chew.md b/.changeset/healthy-ladybugs-chew.md deleted file mode 100644 index 83f53d5c2c..0000000000 --- a/.changeset/healthy-ladybugs-chew.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': minor ---- - -Generated OpenAPI files now have a `.generated.ts` file name and a warning header at the top, to highlight that they should not be edited by hand. diff --git a/.changeset/honest-countries-deny.md b/.changeset/honest-countries-deny.md deleted file mode 100644 index 14c9094592..0000000000 --- a/.changeset/honest-countries-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-jenkins-backend': patch ---- - -Fix handling of slashes in branch names diff --git a/.changeset/hungry-foxes-divide.md b/.changeset/hungry-foxes-divide.md deleted file mode 100644 index 589c899443..0000000000 --- a/.changeset/hungry-foxes-divide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': patch ---- - -Expose all `EntityRelationsGraphProps` to Catalog Graph Page diff --git a/.changeset/hungry-peas-sing.md b/.changeset/hungry-peas-sing.md deleted file mode 100644 index 8c39d33ddd..0000000000 --- a/.changeset/hungry-peas-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-openapi': patch ---- - -Fixed bug in `jsonSchemaRefPlaceholderResolver` where relative $ref files were resolved through file system instead of base URL of file diff --git a/.changeset/khaki-brooms-kiss.md b/.changeset/khaki-brooms-kiss.md deleted file mode 100644 index 76d4ff2cd2..0000000000 --- a/.changeset/khaki-brooms-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': patch ---- - -Display the title of the entity on the explore card if present, otherwise stick to the name diff --git a/.changeset/lazy-keys-work.md b/.changeset/lazy-keys-work.md deleted file mode 100644 index 8a01662929..0000000000 --- a/.changeset/lazy-keys-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-circleci': patch ---- - -Fixes row display for in progress jobs to not display trailing "took" diff --git a/.changeset/mighty-bears-glow.md b/.changeset/mighty-bears-glow.md deleted file mode 100644 index e540cdd8ae..0000000000 --- a/.changeset/mighty-bears-glow.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-search-react': minor -'@backstage/plugin-search': minor ---- - -Add close button & improve search input. - -MUI's Paper wrapping the SearchBar in the SearchPage was removed, we recommend users update their apps accordingly. - -SearchBarBase's TextField's label support added & aria-label uses label string if present, tests relying on the default placeholder value should still work unless custom placeholder was given. diff --git a/.changeset/mighty-cows-greet.md b/.changeset/mighty-cows-greet.md deleted file mode 100644 index 2e871db0c6..0000000000 --- a/.changeset/mighty-cows-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-analytics-module-ga4': minor ---- - -Plugin provides Backstage Analytics API for Google Analytics 4. Once installed and configured, analytics events will be sent to GA4 as your users navigate and use your Backstage instance diff --git a/.changeset/modern-pumpkins-join.md b/.changeset/modern-pumpkins-join.md deleted file mode 100644 index dc0e4a6575..0000000000 --- a/.changeset/modern-pumpkins-join.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Switch `configServiceFactory` to use `ConfigSources` from `@backstage/config-loader` to load config. diff --git a/.changeset/moody-lizards-beam.md b/.changeset/moody-lizards-beam.md deleted file mode 100644 index 68fb9a9e40..0000000000 --- a/.changeset/moody-lizards-beam.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -'@backstage/config-loader': minor ---- - -Introduced a new config source system to replace `loadConfig`. There is a new `ConfigSource` interface along with utilities provided by `ConfigSources`, as well as a number of built-in configuration source implementations. The new system is more flexible and makes it easier to create new and reusable sources of configuration, such as loading configuration from secret providers. - -The following is an example of how to load configuration using the default behavior: - -```ts -const source = ConfigSources.default({ - argv: options?.argv, - remote: options?.remote, -}); -const config = await ConfigSources.toConfig(source); -``` - -The `ConfigSource` interface looks like this: - -```ts -export interface ConfigSource { - readConfigData(options?: ReadConfigDataOptions): AsyncConfigSourceIterator; -} -``` - -It is best implemented using an async iterator: - -```ts -class MyConfigSource implements ConfigSource { - async *readConfigData() { - yield { - config: [ - { - context: 'example', - data: { backend: { baseUrl: 'http://localhost' } }, - }, - ], - }; - } -} -``` diff --git a/.changeset/moody-shrimps-train.md b/.changeset/moody-shrimps-train.md deleted file mode 100644 index 397500e2cb..0000000000 --- a/.changeset/moody-shrimps-train.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': minor ---- - -Add a new scaffolder action for gitlab to ensure a group exists diff --git a/.changeset/new-roses-fail.md b/.changeset/new-roses-fail.md deleted file mode 100644 index 77495c5f54..0000000000 --- a/.changeset/new-roses-fail.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Changed the MembersListCard component to allow displaying aggregated members when viewing a group. Now, a toggle switch can be displayed that lets you switch between showing direct members and aggregated members. - -To enable this new feature, set the showAggregateMembersToggle prop on EntityMembersListCard: - -```jsx -// In packages/app/src/components/catalog/EntityPage.tsx -const groupPage = ( - // ... - - // ... -); -``` diff --git a/.changeset/nine-ties-smoke.md b/.changeset/nine-ties-smoke.md deleted file mode 100644 index f7ae8016be..0000000000 --- a/.changeset/nine-ties-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Bump to using the later v5 versions of `@rjsf/*` diff --git a/.changeset/olive-turkeys-switch.md b/.changeset/olive-turkeys-switch.md deleted file mode 100644 index d208f3b197..0000000000 --- a/.changeset/olive-turkeys-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Fixed bug in queryWithPaging that caused secondary rate limit errors in GitHub with organizations having more than 1000 repositories. This change makes one request per second to avoid concurrency issues. diff --git a/.changeset/perfect-readers-attack.md b/.changeset/perfect-readers-attack.md new file mode 100644 index 0000000000..93d205eb9c --- /dev/null +++ b/.changeset/perfect-readers-attack.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Tweak README diff --git a/.changeset/polite-dingos-train.md b/.changeset/polite-dingos-train.md deleted file mode 100644 index 49ac56a000..0000000000 --- a/.changeset/polite-dingos-train.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -'@backstage/plugin-kubernetes': minor ---- - -Added Pod logs components for Kubernetes plugin - -**BREAKING**: `kubernetesProxyApi` for custom plugins built with components from the Kubernetes plugin apis, `kubernetesProxyApi` should be added to the plugin's API list. - -``` -... -export const kubernetesPlugin = createPlugin({ - id: 'kubernetes', - apis: [ -... - createApiFactory({ - api: kubernetesProxyApiRef, - deps: { - kubernetesApi: kubernetesApiRef, - }, - factory: ({ kubernetesApi }) => - new KubernetesProxyClient({ - kubernetesApi, - }), - }), -``` - -**BREAKING**: `KubernetesDrawer` is now called `KubernetesStructuredMetadataTableDrawer` so that we can do more than just show `StructuredMetadataTable` - -`import { KubernetesDrawer } from "@backstage/plugin-kubernetes"` - -should now be: - -`import { KubernetesStructuredMetadataTableDrawer } from "@backstage/plugin-kubernetes"` diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 759b1b40e2..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,271 +0,0 @@ -{ - "mode": "pre", - "tag": "next", - "initialVersions": { - "example-app": "0.2.82", - "@backstage/app-defaults": "1.3.0", - "example-backend": "0.2.82", - "@backstage/backend-app-api": "0.4.2", - "@backstage/backend-common": "0.18.4", - "@backstage/backend-defaults": "0.1.9", - "@backstage/backend-dev-utils": "0.1.1", - "example-backend-next": "0.0.10", - "@backstage/backend-openapi-utils": "0.0.1", - "@backstage/backend-plugin-api": "0.5.1", - "@backstage/backend-tasks": "0.5.1", - "@backstage/backend-test-utils": "0.1.36", - "@backstage/catalog-client": "1.4.1", - "@backstage/catalog-model": "1.3.0", - "@backstage/cli": "0.22.6", - "@backstage/cli-common": "0.1.12", - "@backstage/cli-node": "0.1.0", - "@backstage/codemods": "0.1.44", - "@backstage/config": "1.0.7", - "@backstage/config-loader": "1.2.0", - "@backstage/core-app-api": "1.7.0", - "@backstage/core-components": "0.13.0", - "@backstage/core-plugin-api": "1.5.1", - "@backstage/create-app": "0.5.0", - "@backstage/dev-utils": "1.0.14", - "e2e-test": "0.2.2", - "@backstage/errors": "1.1.5", - "@backstage/eslint-plugin": "0.1.3", - "@backstage/integration": "1.4.4", - "@backstage/integration-aws-node": "0.1.2", - "@backstage/integration-react": "1.1.12", - "@backstage/release-manifests": "0.0.9", - "@backstage/repo-tools": "0.2.0", - "@techdocs/cli": "1.4.1", - "techdocs-cli-embedded-app": "0.2.81", - "@backstage/test-utils": "1.3.0", - "@backstage/theme": "0.2.19", - "@backstage/types": "1.0.2", - "@backstage/version-bridge": "1.0.4", - "@backstage/plugin-adr": "0.5.0", - "@backstage/plugin-adr-backend": "0.3.2", - "@backstage/plugin-adr-common": "0.2.8", - "@backstage/plugin-airbrake": "0.3.17", - "@backstage/plugin-airbrake-backend": "0.2.17", - "@backstage/plugin-allure": "0.1.33", - "@backstage/plugin-analytics-module-ga": "0.1.28", - "@backstage/plugin-apache-airflow": "0.2.10", - "@backstage/plugin-api-docs": "0.9.2", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.2", - "@backstage/plugin-apollo-explorer": "0.1.10", - "@backstage/plugin-app-backend": "0.3.44", - "@backstage/plugin-auth-backend": "0.18.2", - "@backstage/plugin-auth-node": "0.2.13", - "@backstage/plugin-azure-devops": "0.2.8", - "@backstage/plugin-azure-devops-backend": "0.3.23", - "@backstage/plugin-azure-devops-common": "0.3.0", - "@backstage/plugin-azure-sites": "0.1.6", - "@backstage/plugin-azure-sites-backend": "0.1.6", - "@backstage/plugin-azure-sites-common": "0.1.0", - "@backstage/plugin-badges": "0.2.41", - "@backstage/plugin-badges-backend": "0.1.38", - "@backstage/plugin-bazaar": "0.2.7", - "@backstage/plugin-bazaar-backend": "0.2.7", - "@backstage/plugin-bitbucket-cloud-common": "0.2.5", - "@backstage/plugin-bitrise": "0.1.44", - "@backstage/plugin-catalog": "1.10.0", - "@backstage/plugin-catalog-backend": "1.9.0", - "@backstage/plugin-catalog-backend-module-aws": "0.1.18", - "@backstage/plugin-catalog-backend-module-azure": "0.1.15", - "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.11", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.11", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.9", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.12", - "@backstage/plugin-catalog-backend-module-github": "0.2.7", - "@backstage/plugin-catalog-backend-module-gitlab": "0.2.0", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.3.1", - "@backstage/plugin-catalog-backend-module-ldap": "0.5.11", - "@backstage/plugin-catalog-backend-module-msgraph": "0.5.3", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.10", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.1", - "@backstage/plugin-catalog-common": "1.0.13", - "@internal/plugin-catalog-customized": "0.0.9", - "@backstage/plugin-catalog-graph": "0.2.29", - "@backstage/plugin-catalog-graphql": "0.3.20", - "@backstage/plugin-catalog-import": "0.9.7", - "@backstage/plugin-catalog-node": "1.3.5", - "@backstage/plugin-catalog-react": "1.5.0", - "@backstage/plugin-cicd-statistics": "0.1.19", - "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.13", - "@backstage/plugin-circleci": "0.3.17", - "@backstage/plugin-cloudbuild": "0.3.17", - "@backstage/plugin-code-climate": "0.1.17", - "@backstage/plugin-code-coverage": "0.2.10", - "@backstage/plugin-code-coverage-backend": "0.2.10", - "@backstage/plugin-codescene": "0.1.12", - "@backstage/plugin-config-schema": "0.1.40", - "@backstage/plugin-cost-insights": "0.12.6", - "@backstage/plugin-cost-insights-common": "0.1.1", - "@backstage/plugin-dynatrace": "4.0.0", - "@backstage/plugin-entity-feedback": "0.2.0", - "@backstage/plugin-entity-feedback-backend": "0.1.2", - "@backstage/plugin-entity-feedback-common": "0.1.1", - "@backstage/plugin-entity-validation": "0.1.2", - "@backstage/plugin-events-backend": "0.2.5", - "@backstage/plugin-events-backend-module-aws-sqs": "0.1.6", - "@backstage/plugin-events-backend-module-azure": "0.1.6", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.6", - "@backstage/plugin-events-backend-module-gerrit": "0.1.6", - "@backstage/plugin-events-backend-module-github": "0.1.6", - "@backstage/plugin-events-backend-module-gitlab": "0.1.6", - "@backstage/plugin-events-backend-test-utils": "0.1.6", - "@backstage/plugin-events-node": "0.2.5", - "@internal/plugin-todo-list": "1.0.12", - "@internal/plugin-todo-list-backend": "1.0.12", - "@internal/plugin-todo-list-common": "1.0.10", - "@backstage/plugin-explore": "0.4.2", - "@backstage/plugin-explore-backend": "0.0.6", - "@backstage/plugin-explore-common": "0.0.1", - "@backstage/plugin-explore-react": "0.0.28", - "@backstage/plugin-firehydrant": "0.2.1", - "@backstage/plugin-fossa": "0.2.49", - "@backstage/plugin-gcalendar": "0.3.13", - "@backstage/plugin-gcp-projects": "0.3.36", - "@backstage/plugin-git-release-manager": "0.3.30", - "@backstage/plugin-github-actions": "0.5.17", - "@backstage/plugin-github-deployments": "0.1.48", - "@backstage/plugin-github-issues": "0.2.6", - "@backstage/plugin-github-pull-requests-board": "0.1.11", - "@backstage/plugin-gitops-profiles": "0.3.35", - "@backstage/plugin-gocd": "0.1.23", - "@backstage/plugin-graphiql": "0.2.49", - "@backstage/plugin-graphql-backend": "0.1.34", - "@backstage/plugin-graphql-voyager": "0.1.2", - "@backstage/plugin-home": "0.5.0", - "@backstage/plugin-ilert": "0.2.6", - "@backstage/plugin-jenkins": "0.7.16", - "@backstage/plugin-jenkins-backend": "0.1.34", - "@backstage/plugin-jenkins-common": "0.1.15", - "@backstage/plugin-kafka": "0.3.17", - "@backstage/plugin-kafka-backend": "0.2.37", - "@backstage/plugin-kubernetes": "0.8.0", - "@backstage/plugin-kubernetes-backend": "0.10.0", - "@backstage/plugin-kubernetes-common": "0.6.2", - "@backstage/plugin-lighthouse": "0.4.2", - "@backstage/plugin-lighthouse-backend": "0.2.0", - "@backstage/plugin-lighthouse-common": "0.1.1", - "@backstage/plugin-linguist": "0.1.2", - "@backstage/plugin-linguist-backend": "0.2.1", - "@backstage/plugin-linguist-common": "0.1.0", - "@backstage/plugin-microsoft-calendar": "0.1.2", - "@backstage/plugin-newrelic": "0.3.35", - "@backstage/plugin-newrelic-dashboard": "0.2.10", - "@backstage/plugin-octopus-deploy": "0.1.1", - "@backstage/plugin-org": "0.6.7", - "@backstage/plugin-org-react": "0.1.6", - "@backstage/plugin-pagerduty": "0.5.10", - "@backstage/plugin-periskop": "0.1.15", - "@backstage/plugin-periskop-backend": "0.1.15", - "@backstage/plugin-permission-backend": "0.5.19", - "@backstage/plugin-permission-common": "0.7.5", - "@backstage/plugin-permission-node": "0.7.7", - "@backstage/plugin-permission-react": "0.4.12", - "@backstage/plugin-playlist": "0.1.8", - "@backstage/plugin-playlist-backend": "0.3.0", - "@backstage/plugin-playlist-common": "0.1.6", - "@backstage/plugin-proxy-backend": "0.2.38", - "@backstage/plugin-puppetdb": "0.1.0", - "@backstage/plugin-rollbar": "0.4.17", - "@backstage/plugin-rollbar-backend": "0.1.41", - "@backstage/plugin-scaffolder": "1.13.0", - "@backstage/plugin-scaffolder-backend": "1.13.0", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.19", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.12", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.4", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.17", - "@backstage/plugin-scaffolder-common": "1.2.7", - "@backstage/plugin-scaffolder-node": "0.1.2", - "@backstage/plugin-scaffolder-react": "1.3.0", - "@backstage/plugin-search": "1.2.0", - "@backstage/plugin-search-backend": "1.3.0", - "@backstage/plugin-search-backend-module-catalog": "0.1.0", - "@backstage/plugin-search-backend-module-elasticsearch": "1.2.0", - "@backstage/plugin-search-backend-module-explore": "0.1.0", - "@backstage/plugin-search-backend-module-pg": "0.5.5", - "@backstage/plugin-search-backend-module-techdocs": "0.1.0", - "@backstage/plugin-search-backend-node": "1.2.0", - "@backstage/plugin-search-common": "1.2.3", - "@backstage/plugin-search-react": "1.5.2", - "@backstage/plugin-sentry": "0.5.2", - "@backstage/plugin-shortcuts": "0.3.9", - "@backstage/plugin-sonarqube": "0.6.6", - "@backstage/plugin-sonarqube-backend": "0.1.9", - "@backstage/plugin-sonarqube-react": "0.1.5", - "@backstage/plugin-splunk-on-call": "0.4.6", - "@backstage/plugin-stack-overflow": "0.1.13", - "@backstage/plugin-stack-overflow-backend": "0.2.0", - "@backstage/plugin-stackstorm": "0.1.1", - "@backstage/plugin-tech-insights": "0.3.9", - "@backstage/plugin-tech-insights-backend": "0.5.10", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.28", - "@backstage/plugin-tech-insights-common": "0.2.10", - "@backstage/plugin-tech-insights-node": "0.4.2", - "@backstage/plugin-tech-radar": "0.6.3", - "@backstage/plugin-techdocs": "1.6.1", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.12", - "@backstage/plugin-techdocs-backend": "1.6.1", - "@backstage/plugin-techdocs-module-addons-contrib": "1.0.12", - "@backstage/plugin-techdocs-node": "1.7.0", - "@backstage/plugin-techdocs-react": "1.1.5", - "@backstage/plugin-todo": "0.2.19", - "@backstage/plugin-todo-backend": "0.1.41", - "@backstage/plugin-user-settings": "0.7.2", - "@backstage/plugin-user-settings-backend": "0.1.8", - "@backstage/plugin-vault": "0.1.11", - "@backstage/plugin-vault-backend": "0.3.0", - "@backstage/plugin-xcmetrics": "0.2.37", - "@backstage/plugin-analytics-module-ga4": "0.0.0" - }, - "changesets": [ - "afraid-shirts-train", - "backend-like-a-tattoo", - "beige-tigers-matter", - "brown-eyes-yell", - "calm-wolves-taste", - "chilly-fireants-type", - "clean-lobsters-brake", - "cold-drinks-exercise", - "create-app-1682437922", - "curvy-months-appear", - "dry-boats-sniff", - "dull-wombats-stare", - "eighty-olives-live", - "fifty-laws-count", - "five-tigers-whisper", - "fresh-moons-unite", - "funny-trains-sniff", - "good-lions-approve", - "green-cheetahs-cover", - "healthy-ladybugs-chew", - "honest-countries-deny", - "hungry-foxes-divide", - "lazy-keys-work", - "mighty-bears-glow", - "mighty-cows-greet", - "modern-pumpkins-join", - "moody-lizards-beam", - "nine-ties-smoke", - "olive-turkeys-switch", - "polite-dingos-train", - "pretty-gifts-greet", - "quick-flies-guess", - "red-cheetahs-invite", - "rotten-chefs-jog", - "serious-hornets-remember", - "six-mails-shout", - "slimy-turkeys-return", - "soft-readers-exist", - "swift-fishes-run", - "tame-games-rule", - "thick-parents-pump", - "tough-moles-whisper", - "unlucky-plants-give", - "warm-lamps-tease" - ] -} diff --git a/.changeset/pretty-gifts-greet.md b/.changeset/pretty-gifts-greet.md deleted file mode 100644 index 965f714a61..0000000000 --- a/.changeset/pretty-gifts-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Add missing @rjsf/core dependency diff --git a/.changeset/quick-flies-guess.md b/.changeset/quick-flies-guess.md deleted file mode 100644 index 73e5589b98..0000000000 --- a/.changeset/quick-flies-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Added `FrontendHostDiscovery` for config driven discovery implementation diff --git a/.changeset/quiet-bikes-smash.md b/.changeset/quiet-bikes-smash.md deleted file mode 100644 index ca751adaf7..0000000000 --- a/.changeset/quiet-bikes-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-openapi-utils': patch ---- - -Corrected resolution of parameter nested schema to use central schemas. diff --git a/.changeset/rare-elephants-arrive.md b/.changeset/rare-elephants-arrive.md deleted file mode 100644 index d27f763d1f..0000000000 --- a/.changeset/rare-elephants-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-puppetdb': patch ---- - -Fixes import paths and updates documentation diff --git a/.changeset/red-cheetahs-invite.md b/.changeset/red-cheetahs-invite.md deleted file mode 100644 index ef1711c761..0000000000 --- a/.changeset/red-cheetahs-invite.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-octopus-deploy': minor ---- - -Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102. -Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object. diff --git a/.changeset/rotten-chefs-jog.md b/.changeset/rotten-chefs-jog.md deleted file mode 100644 index 120520c087..0000000000 --- a/.changeset/rotten-chefs-jog.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Improvements to the `scaffolder/next` buttons UX: - -- Added padding around the "Create" button in the `Stepper` component -- Added a button bar that includes the "Cancel" and "Start Over" buttons to the `OngoingTask` component. The state of these buttons match their existing counter parts in the Context Menu -- Added a "Show Button Bar"/"Hide Button Bar" item to the `ContextMenu` component diff --git a/.changeset/serious-hornets-remember.md b/.changeset/serious-hornets-remember.md deleted file mode 100644 index 05221cd055..0000000000 --- a/.changeset/serious-hornets-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-circleci': patch ---- - -Hide empty time field data for queued builds which haven't started yet diff --git a/.changeset/shaggy-gorillas-occur.md b/.changeset/shaggy-gorillas-occur.md new file mode 100644 index 0000000000..ce7c2aba3b --- /dev/null +++ b/.changeset/shaggy-gorillas-occur.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-linguist-backend': minor +--- + +**BREAKING**: Removed public constructor from `LinguistBackendApi`. Removed export of `LinguistBackendDatabase` and `LinguistBackendStore` + +Several improvements to the Linguist backend have been made: + +- Added tests for the `LinguistBackendDatabase` and `LinguistBackendApi` +- Added support for using SQLite as a database, helpful for local development +- Removed the default from the `processes_date` column +- Converted the `LinguistBackendApi` into an Interface +- Added the `LinguistBackendClient` which implements the `LinguistBackendApi` Interface +- Unprocessed entities will get processed before stale entities +- Entities in the Linguist database but not in the Catalog anymore will be deleted +- Improved the README's headings diff --git a/.changeset/short-seahorses-kiss.md b/.changeset/short-seahorses-kiss.md new file mode 100644 index 0000000000..0127e4c575 --- /dev/null +++ b/.changeset/short-seahorses-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Change deprecated local references to import from shared `plugin-techdocs-react` plugin diff --git a/.changeset/six-mails-shout.md b/.changeset/six-mails-shout.md deleted file mode 100644 index f803e0858e..0000000000 --- a/.changeset/six-mails-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-shortcuts': patch ---- - -Marked `LocalStoredShortcuts` as deprecated, replacing it with `DefaultShortcutsApi` whose naming more clearly suggests that the shortcuts aren't necessarily stored locally (it depends on the storage implementation). diff --git a/.changeset/slimy-turkeys-return.md b/.changeset/slimy-turkeys-return.md deleted file mode 100644 index db10000509..0000000000 --- a/.changeset/slimy-turkeys-return.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@backstage/plugin-permission-node': patch ---- - -`createPermissionIntegrationRouter` now accepts rules and permissions for multiple resource types. Example: - -```typescript -createPermissionIntegrationRouter({ - resources: [ - { - resourceType: 'resourceType-1', - permissions: permissionsResourceType1, - rules: rulesResourceType1, - }, - { - resourceType: 'resourceType-2', - permissions: permissionsResourceType2, - rules: rulesResourceType2, - }, - ], -}); -``` diff --git a/.changeset/soft-readers-exist.md b/.changeset/soft-readers-exist.md deleted file mode 100644 index 8fce13caca..0000000000 --- a/.changeset/soft-readers-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Added `HostDiscovery` to supersede deprecated `SingleHostDiscovery` (deprecated due to name) diff --git a/.changeset/stupid-seas-stare.md b/.changeset/stupid-seas-stare.md deleted file mode 100644 index f3d4f5e1f7..0000000000 --- a/.changeset/stupid-seas-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fix accessibility issue on controlled select input on tab navigation + keyboard enter/space action. diff --git a/.changeset/swift-fishes-run.md b/.changeset/swift-fishes-run.md deleted file mode 100644 index ee3d1217ed..0000000000 --- a/.changeset/swift-fishes-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Bump minimum required version of `vm2` to be 3.9.17 diff --git a/.changeset/tame-games-rule.md b/.changeset/tame-games-rule.md deleted file mode 100644 index 408c8ca14b..0000000000 --- a/.changeset/tame-games-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Pin some octokit dependencies to avoid failing typescript build under `tsc:full` diff --git a/.changeset/thick-parents-pump.md b/.changeset/thick-parents-pump.md deleted file mode 100644 index ba65e10610..0000000000 --- a/.changeset/thick-parents-pump.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder-node': patch ---- - -Update typing for `RouterOptions::actions` and `ScaffolderActionsExtensionPoint::addActions` to allow any kind of action being assigned to it. diff --git a/.changeset/thin-ways-exist.md b/.changeset/thin-ways-exist.md deleted file mode 100644 index fd1ecb62a4..0000000000 --- a/.changeset/thin-ways-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': patch ---- - -Fix text-overflow UI issue for Lifecycle spans in SearchFilter checkbox labels. diff --git a/.changeset/tough-moles-whisper.md b/.changeset/tough-moles-whisper.md deleted file mode 100644 index 14dd76c116..0000000000 --- a/.changeset/tough-moles-whisper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Added the ability to display a timeline to each entry in the details box diff --git a/.changeset/twelve-zebras-repair.md b/.changeset/twelve-zebras-repair.md deleted file mode 100644 index 8d74080c38..0000000000 --- a/.changeset/twelve-zebras-repair.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch ---- - -Added an OpenAPI 3.0 spec and enforced schema-first model on the router. diff --git a/.changeset/two-gorillas-drop.md b/.changeset/two-gorillas-drop.md deleted file mode 100644 index 72de66dbff..0000000000 --- a/.changeset/two-gorillas-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': patch ---- - -Updated the example code in the "Customization" section of the README to make the imports match the components used. diff --git a/.changeset/unlucky-plants-give.md b/.changeset/unlucky-plants-give.md deleted file mode 100644 index 504b475727..0000000000 --- a/.changeset/unlucky-plants-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Start capturing sidebar click events in analytics by default. diff --git a/.changeset/warm-lamps-tease.md b/.changeset/warm-lamps-tease.md deleted file mode 100644 index 954197dd13..0000000000 --- a/.changeset/warm-lamps-tease.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': minor ---- - -Update `aws-sdk` client from v2 to v3. - -**BREAKING**: The `AwsIamKubernetesAuthTranslator` class no longer exposes the following methods `awsGetCredentials`, `getBearerToken`, `getCredentials` and `validCredentials`. There is no replacement for these methods. diff --git a/.github/uffizzi/docker-compose.uffizzi.yml b/.github/uffizzi/docker-compose.uffizzi.yml index 76a7b4eafc..f2e9bbeee6 100644 --- a/.github/uffizzi/docker-compose.uffizzi.yml +++ b/.github/uffizzi/docker-compose.uffizzi.yml @@ -14,6 +14,7 @@ services: POSTGRES_PORT: 5432 POSTGRES_USER: postgres POSTGRES_PASSWORD: kiTMoTsiEuyQ43GrL4Hv + REF_NAME: ${GITHUB_SHA} NODE_ENV: production deploy: resources: diff --git a/.github/uffizzi/uffizzi.production.app-config.yaml b/.github/uffizzi/uffizzi.production.app-config.yaml index 30cffa11c9..3b24c20b3d 100644 --- a/.github/uffizzi/uffizzi.production.app-config.yaml +++ b/.github/uffizzi/uffizzi.production.app-config.yaml @@ -28,6 +28,7 @@ backend: credentials: true csp: connect-src: ["'self'", 'http:', 'https:'] + img-src: ["'self'", 'data:', 'https://cdnjs.cloudflare.com'] # Content-Security-Policy directives follow the Helmet format: https://helmetjs.github.io/#reference # Default Helmet Content-Security-Policy values can be removed by setting the key to false @@ -41,15 +42,18 @@ auth: catalog: locations: - type: url - target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/all.yaml + target: https://github.com/backstage/backstage/blob/${REF_NAME}/packages/catalog-model/examples/all.yaml - type: url - target: https://github.com/backstage/backstage/blob/master/packages/catalog-model/examples/acme-corp.yaml + target: https://github.com/backstage/backstage/blob/${REF_NAME}/plugins/techdocs-backend/examples/documented-component-uffizzi/catalog-info.yaml + + - type: url + target: https://github.com/backstage/backstage/blob/${REF_NAME}/packages/catalog-model/examples/acme-corp.yaml rules: - allow: [User, Group] - type: url - target: https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/sample-templates/all-templates.yaml + target: https://github.com/backstage/backstage/blob/${REF_NAME}/plugins/scaffolder-backend/sample-templates/all-templates.yaml rules: - allow: [Template] @@ -124,7 +128,7 @@ proxy: techdocs: builder: 'local' # Alternatives - 'external' generator: - runIn: 'docker' + runIn: 'local' # dockerImage: my-org/techdocs # use a custom docker image # pullImage: true # or false to disable automatic pulling of image (e.g. if custom docker login is required) publisher: diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 83fba8aa56..68fbdabb00 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -188,6 +188,7 @@ learnings Leasot lerna Lerna +lightbox limitranges LocalStack lockdown @@ -247,6 +248,7 @@ Olausson Oldsberg onboarding Onboarding +OpenSearch OpenShift orgs padding @@ -314,6 +316,7 @@ scaffolded scaffolder Scaffolder scrollbar +sdks seb semlas semver @@ -341,6 +344,8 @@ stdout storable stringified stringify +subcommand +subcommands subcomponent subcomponents subfolder @@ -389,6 +394,7 @@ transpilers truthy TSDoc typeahead +Uffizzi ui unbreak Unconference diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86ac320ac7..ec0a791dcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: run: node scripts/verify-api-reference.js - name: verify openapi yaml file matches generated ts file - run: yarn backstage-repo-tools schema:openapi:verify + run: yarn backstage-repo-tools schema openapi verify - name: verify doc links run: node scripts/verify-links.js diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index ee629bbafe..1b031f50ad 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -81,7 +81,7 @@ jobs: BACKSTAGE_IMAGE=$(echo ${{ needs.build-backstage.outputs.tags }}) export BACKSTAGE_IMAGE # Render simple template from environment variables. - envsubst '$BACKSTAGE_IMAGE' < .github/uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml + envsubst '$BACKSTAGE_IMAGE $GITHUB_SHA' < .github/uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml cat docker-compose.rendered.yml - name: Upload Rendered Compose File as Artifact uses: actions/upload-artifact@v3 diff --git a/ADOPTERS.md b/ADOPTERS.md index d4dcf8db7e..d3fc55966f 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -14,7 +14,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications | | [Kiwi.com](https://kiwi.com) | [@aexvir](https://github.com/aexvir) | Replacing the frontend of [The Zoo](https://github.com/kiwicom/the-zoo), their service registry. | | [Voi](https://www.voiscooters.com/) | [@K-Phoen](https://github.com/K-Phoen) | Developer portal, main gateway to our infrastructure, documentation and internal tooling. | -| [Talkdesk](https://www.talkdesk.com) | [@jaime-talkdesk](https://github.com/jaime-talkdesk) | Initial work for Engineering Portal and Self Provisioning to R&D | +| [Talkdesk](https://www.talkdesk.com) | [@atmcarmo](https://github.com/atmcarmo) | Engineering Portal with all of our apps and services, overview about our deployment regions and scaffolding new services. | | [Wealthsimple](https://www.wealthsimple.com) | [@andrewthauer](https://github.com/andrewthauer) | Developer portal, service catalog, documentation and tooling | | [Grab](https://www.grab.com) | [@althafh](https://github.com/althafh) | Initial work as a unified interface for all of Grab's internal tooling | | [Telenor Sweden](https://www.telenor.se) | [@O5ten](https://github.com/O5ten) | Building a developer portal for scaffolding projects towards our unified build environment and microservice stacks | @@ -132,7 +132,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Tink](https://tink.com/) | [Sebastian Olsson](https://github.com/Sebelino), [Błażej Szum](https://github.com/blazejszumtink), [Anders Eurenius Runvald](https://github.com/anders-er-at-tink) | Internal developer portal which provides templates for creating new Java or Go microservices seamlessly. Also includes a tech radar and a visualization of our CD pipeline. | | [Brandwatch](https://brandwatch.com) | [Stefan Buck](https://github.com/stefanbuck) | Our primary focus is on the service catalog. Backstage is replacing our homemade service catalog. The switch was quite simple due to the catalog processor API. | | [Laybuy](https://www.laybuy.com) | [Chris Simmons](https://github.com/contrarianchris) | Backstage is the heart of Laybuy’s new centralised Development Platform, bringing disparate development tools and experiences into a single easy-to-use portal. It simplifies software and API discovery, project scaffolding, and technical documentation, enabling us to embrace golden path development and automate software standards. | -| [Sendinblue](https://engineering.sendinblue.com/) | [Tanguy Antoine](mailto:antoine.tanguy@sendinblue.com) | Helps us drive the change at scale. Puts light on services, resources, and dependencies. One tool that rules them all through plugins we created for that purpose. We are aiming to put Backstage at the center of every developer's work (Actionable items, Debugging, Monitoring, Provisioning, etc...) to improve their happiness | +| [Brevo](https://engineering.brevo.com/) | [Tanguy Antoine](mailto:antoine.tanguy@brevo.com) | Helps us drive the change at scale. Puts light on services, resources, and dependencies. One tool that rules them all through plugins we created for that purpose. We are aiming to put Backstage at the center of every developer's work (Actionable items, Debugging, Monitoring, Provisioning, etc...) to improve their happiness | | [SafetyCulture](https://safetyculture.com/) | [@R-cen](https://github.com/R-cen), [@lachlancooper](https://github.com/lachlancooper), [@hkf57](https://github.com/hkf57) | Internal developer portal to provide a centralized place for engineers to see an overview of their team's services and information related to the service from other systems. Initially focused on the software catalog, techdocs and search. | | [Sana Life Science](https://sanalifescience.com) | [Joe Hillyard](mailto:joe@sanalifescience.com) | API Catalog, Tools Management & Control Hub | | [Ndustrial](https://ndustrial.io) | [Jonathan Skubic](mailto:jonathan@ndustrial.io) | Software Project Catalog | @@ -244,4 +244,6 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Quantum Metric](https://www.quantummetric.com/) | [Eric Irwin](https://www.linkedin.com/in/ericirwin1124/) | Backstage is used within our Developer Experience Platform (DXP) in order to increase self-service, standardization and discoverability across our Engineering teams. | | [VodafoneZiggo](https://www.vodafoneziggo.nl/) | [Peter Macdonald](https://github.com/Parsifal-M) | We use Backstage as our go-to platform for managing our internal tools and services. With Backstage, we can easily discover and access all the services we need to do our work, whether it's deploying code, managing infrastructure, or accessing documentation. We appreciate the standardized, consistent interface and the ability to easily create custom plugins to integrate with our existing workflows. Overall, Backstage is streamlining our internal operations and helps us work more efficiently as a team. | | [Volvo Cars](https://www.volvocars.com) | [Martin Wänerskär](https://github.com/martin-wanerskar) | Internal developer portal with intent to unify infrastructure tooling, services, and developer documentation under a single, easy-to-use interface. | -| [Mercantil Andina](https://www.mercantilandina.com.ar/) | [Sebastian Paredero](https://www.linkedin.com/in/sebastian-paredero/), [Matias Javier Gomez](https://www.linkedin.com/in/matias-javier-gomez-140540a3/), [Gustavo Wilgenhoff](https://github.com/wilgustavo) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. | \ No newline at end of file +| [Mercantil Andina](https://www.mercantilandina.com.ar/) | [Sebastian Paredero](https://www.linkedin.com/in/sebastian-paredero/), [Matias Javier Gomez](https://www.linkedin.com/in/matias-javier-gomez-140540a3/), [Gustavo Wilgenhoff](https://github.com/wilgustavo) | Developer portal: documentation, service templates, org structure, service catalog, plugins for integration with internal systems. | +| [Livelo](https://www.livelo.com.br) | [Felipe Nardon](https://www.linkedin.com/in/felipe-nardon-dos-santos/), [Yves Galvão](https://www.linkedin.com/in/yvesgalvao/), [Isaque Rocha](https://www.linkedin.com/in/isaque-rocha/) | Internal platform that aims to reduce the teams' cognitive load through self-service, abstracting processes that are now part of the teams' daily lives, enabling a centralized management of documentation, catalog, metrics and knowledge. | +| [Worten](https://www.worten.pt) | [@elisiariocouto](https://github.com/elisiariocouto) | We are proud to be an adopter of Backstage. Our goal is to make our Backstage installation the go-to location for every developer. To achieve this, we developed a custom plugin to populate Backstage's catalog with information from our internal deployment tool. As a result, we now have full visibility of all Worten systems, components, APIs, messaging topics, and documentation. We also migrated the internal deployment tool's Web UI to Backstage. Currently, we are working on Backstage's Software Templates feature. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7828791080..ed1baa133a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,10 +92,14 @@ For those contributors who have earned write access to the repository, when a pu ## Code of Conduct -This project adheres to the [Spotify FOSS Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code. +This project adheres to the [CNCF Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code. [code-of-conduct]: https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md ## Security Issues? See [SECURITY](SECURITY.md). + +## Accessibility + +We encourage you to catch any accessibility issues already in the development phase of new features to Backstage, see our [Accessibility documentation](./docs/accessibility/index.md) for more details. diff --git a/OWNERS.md b/OWNERS.md index 0d2040d770..25ada5853e 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -77,6 +77,20 @@ Scope: The TechDocs plugin and related tooling | Morgan Bentell | Spotify | Pulp Fiction | [agentbellnorm](http://github.com/agentbellnorm) | morganbentell#9030 | | Raghunandan Balachandran | Spotify | Pulp Fiction | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | +## Incubating Project Areas + +These incubating project areas have shared ownership with @backstage/maintainers. + +### OpenAPI Tooling + +Team: @backstage/openapi-tooling-maintainers + +Scope: Tooling for frontend and backend schema-first OpenAPI development. + +| Name | Organization | GitHub | Discord | +| -------------- | ------------ | --------------------------------------- | ------------- | +| Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | + ## Sponsors | Name | Organization | GitHub | Email | diff --git a/README.md b/README.md index 4952eab10f..5676e262f8 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ ![Code style](https://img.shields.io/badge/code_style-prettier-ff69b4.svg) [![Codecov](https://img.shields.io/codecov/c/github/backstage/backstage)](https://codecov.io/gh/backstage/backstage) [![](https://img.shields.io/github/v/release/backstage/backstage)](https://github.com/backstage/backstage/releases) +[![Uffizzi](https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.uffizzi.com%2Fapi%2Fv1%2Fpublic%2Fshields%2Fgithub.com%2Fbackstage%2Fbackstage)](https://app.uffizzi.com/ephemeral-environments/backstage/backstage) ## What is Backstage? diff --git a/contrib/catalog/ImmediateEntityProvider.ts b/contrib/catalog/ImmediateEntityProvider.ts index b66c62e330..33ae6697f6 100644 --- a/contrib/catalog/ImmediateEntityProvider.ts +++ b/contrib/catalog/ImmediateEntityProvider.ts @@ -9,8 +9,8 @@ import { DeferredEntity, EntityProvider, EntityProviderConnection, - parseEntityYaml, -} from '@backstage/plugin-catalog-backend'; +} from '@backstage/plugin-catalog-node'; +import { parseEntityYaml } from '@backstage/plugin-catalog-backend'; import bodyParser from 'body-parser'; import express from 'express'; import Router from 'express-promise-router'; diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 49b6ae0a4d..c14eaebb54 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -82,10 +82,20 @@ export const createAuthMiddleware = async ( }; ``` +Install cookie-parser: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend cookie-parser +``` + +Update routes in `packages/backend/src/index.ts`: + ```typescript // packages/backend/src/index.ts from a create-app deployment import { createAuthMiddleware } from './authMiddleware'; +import cookieParser from 'cookie-parser'; // ... diff --git a/docs/accessibility/index.md b/docs/accessibility/index.md new file mode 100644 index 0000000000..24685b95ce --- /dev/null +++ b/docs/accessibility/index.md @@ -0,0 +1,60 @@ +--- +id: index +title: Backstage Accessibility +description: Documentation on Backstage Accessibility +--- + +In an effort to bake accessibility practices further into our process of building features for Backstage, we support automated CI tests for some of our core features in the OSS project: Software Catalog, Software Templates, Search, and TechDocs. As these are just a few of the many plugins out there, we encourage you to consider the accessibility implications of your work on Backstage in order to build a great experience for everyone. + +## How to contribute + +There are multiple ways to contribute to making Backstage more accessible, you'll find below a list of examples to help you get started. + +### Run Lighthouse in CI on your plugin + +If your plugin lives in the [Backstage main repository](https://github.com/backstage/backstage/) you can modify the [urls in the Lighthouse config](https://github.com/backstage/backstage/blob/39ba2284d73885b7ca8290cb38e2b1e4d983c8d6/lighthouserc.js#L19-L34) to run the Lighthouse checks on urls where your plugin exists as well. E.g. + +```diff + ci: { + collect: { + url: [ ++ /** Your plugin paths */ ++ 'http://localhost:3000/your-plugin-path, + /** Software Catalog */ + 'http://localhost:3000/catalog', + 'http://localhost:3000/catalog-import', + 'http://localhost:3000/catalog/default/component/backstage', + ... + ], + settings: { + ... + }, + ... + }, + assert: { + ... + }, + }, +``` + +To make sure the [Accessibility Github workflow](https://github.com/backstage/backstage/blob/master/.github/workflows/verify_accessibility.yml) is running when changes are made to your plugin folders, modify the [list of paths](https://github.com/backstage/backstage/blob/10759b6ad2561bd86183ad940256f9a309c7a6b0/.github/workflows/verify_accessibility.yml#L7-L16). + +### Run the Lighthouse CLI locally when developing new features + +If you want to use the Lighthouse CLI and run the checks based on the config you can use the following command: + +``` +yarn dlx @lhci/cli@0.11.x autorun +``` + +> Note: running this command will use the [Lighthouse config](https://github.com/backstage/backstage/blob/39ba2284d73885b7ca8290cb38e2b1e4d983c8d6/lighthouserc.js#L19-L34) so make sure to adjust it to your needs if needed. + +### Use Lighthouse Github Action on your own repo + +If your Backstage plugin lives outside of the [Backstage main repository](https://github.com/backstage/backstage/), and you use GitHub Actions for continuous integration, we encourage you to add and modify the [Accessibility GitHub workflow](https://github.com/backstage/backstage/blob/master/.github/workflows/verify_accessibility.yml) to your needs. + +### Report identified issues + +It’s important to remember that automated checks can only catch a small number of accessibility issues, therefore we also encourage you to conduct manual testing of your plugins using Assistive technology (screen readers, alternative navigation, and screen magnifiers are a few examples). + +If you have identified accessibility issues and don’t have time to contribute a fix, please open an issue over at [Backstage Issues](https://github.com/backstage/backstage/issues) to let us know. diff --git a/docs/features/kubernetes/authentication.md b/docs/features/kubernetes/authentication.md index d44d3a4a64..ddeabb5db0 100644 --- a/docs/features/kubernetes/authentication.md +++ b/docs/features/kubernetes/authentication.md @@ -66,6 +66,7 @@ as `401` or similar. The providers available as client side are: +- `aks` - `google` - `oidc` diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index 458637f316..9280c4f020 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -104,12 +104,13 @@ cluster. Valid values are: | Value | Description | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | -| `google` | This will use a user's Google auth token from the [Google auth plugin](https://backstage.io/docs/auth/) to access the Kubernetes API. | +| `aks` | This will use a user's AKS access token from the [Microsoft auth provider](https://backstage.io/docs/auth/microsoft/provider) to access the Kubernetes API on AKS clusters. | | `aws` | This will use AWS credentials to access resources in EKS clusters | -| `googleServiceAccount` | This will use the Google Cloud service account credentials to access resources in clusters | | `azure` | This will use [Azure Identity](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to access resources in clusters | +| `google` | This will use a user's Google access token from the [Google auth provider](https://backstage.io/docs/auth/google/provider) to access the Kubernetes API on GKE clusters. | +| `googleServiceAccount` | This will use the Google Cloud service account credentials to access resources in clusters | | `oidc` | This will use [Oidc Tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) to authenticate to the Kubernetes API. When this is used the `oidcTokenProvider` field should also be set. Please note the cluster must support OIDC, at the time of writing AKS clusters do not support OIDC. | +| `serviceAccount` | This will use a Kubernetes [service account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) to access the Kubernetes API. When this is used the `serviceAccountToken` field should also be set. | Check the [Kubernetes Authentication][4] section for additional explanation. diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 9fb57cb82f..1c9825d5ca 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -239,17 +239,18 @@ Example: `visits-tracking-service`, `CircleciBuildsDumpV2_avro_gcs` ### `namespace` [optional] -The ID of a namespace that the entity belongs to. This is a string that follows -the same format restrictions as `name` above. +The ID of a namespace that the entity belongs to. This field is optional, and +currently has no special semantics apart from bounding the name uniqueness +constraint if specified. It is reserved for future use and may get broader +semantic implication later. -This field is optional, and currently has no special semantics apart from -bounding the name uniqueness constraint if specified. It is reserved for future -use and may get broader semantic implication later. For now, it is recommended -to not specify a namespace unless you have specific need to do so. This means -the entity belongs to the `"default"` namespace. +For now, it is recommended to not specify a namespace unless you have specific +need to do so. This means the entity belongs to the `"default"` namespace. -Namespaces may also be part of the catalog, and are `v1` / `Namespace` entities, -i.e. not Backstage specific but the same as in Kubernetes. +Namespaces must be sequences of `[a-zA-Z0-9]`, possibly separated by `-`, at +most 63 characters in total. Namespace names are case insensitive and will be rendered as lower case in most places. + +Example: `tracking-services`, `payment` ### `uid` [output] diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index 15e6a833cc..67bcb6c179 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -510,10 +510,8 @@ take a look at, or you can Each individual step can output some variables that can be used in the scaffolder frontend for after the job is finished. This is useful for things -like linking to the entity that has been created with the backend, and also -linking to the created repository. - -The main two that are used are the following: +like linking to the entity that has been created with the backend, linking +to the created repository, or showing Markdown text blobs. ```yaml output: @@ -523,6 +521,10 @@ output: - title: Open in catalog icon: catalog entityRef: ${{ steps['register'].output.entityRef }} # link to the entity that has been ingested to the catalog + text: + - title: More information + content: | + **Entity URL:** `${{ steps['publish'].output.remoteUrl }}` ``` ## The templating syntax diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index 2196a1a36d..87995746d8 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -243,6 +243,8 @@ integrations: token: ${GITHUB_TOKEN} # this will use the environment variable GITHUB_TOKEN ``` +> Note: If you've updated the configuration for your integration, it's likely that the backend will need a restart to apply these changes. To do this, stop the running instance in your terminal with `Control-C`, then start it again with `yarn dev`. Once the backend has restarted, retry the operation. + Some helpful links, for if you want to learn more about: - [Other available integrations](../integrations/) diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 7398e9a311..820f5ef394 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -21,6 +21,9 @@ you to use the [Contributors](contributors.md) guide to do a repository-based in - Access to a Unix-based operating system, such as Linux, MacOS or [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) +- A GNU-like build environment available at the command line. + For example, on Debian/Ubuntu you will want to have the `make` and `build-essential` packages installed. + On MacOS, you will want to have run `xcode-select --install` to get the XCode command line build tooling in place. - An account with elevated rights to install the dependencies - `curl` or `wget` installed - Node.js [Active LTS Release](https://nodejs.org/en/blog/release/) installed using one of these diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index ccffe60bd1..39532e806f 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -65,6 +65,42 @@ export default async function createPlugin( } ``` +Alternatively, if you wish to ingest data from multiple GitHub organizations you can use +the `GithubMultiOrgEntityProvider` instead. Note that by default, this provider will namespace +groups according to the org they originate from to avoid potential name duplicates: + +```ts title="packages/backend/src/plugins/catalog.ts" +/* highlight-add-next-line */ +import { GithubMultiOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const builder = await CatalogBuilder.create(env); + + /* highlight-add-start */ + // The GitHub URL below needs to match a configured integrations.github entry + // specified in your app-config. + builder.addEntityProvider( + GithubMultiOrgEntityProvider.fromConfig(env.config, { + id: 'production', + githubUrl: 'https://github.com', + // Set the following to list the GitHub orgs you wish to ingest from. You can + // also omit this option to ingest all orgs accessible by your GitHub integration + orgs: ['org-a', 'org-b'], + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 60 }, + timeout: { minutes: 15 }, + }), + }), + ); + /* highlight-add-end */ + + // .. +} +``` + ## Installation with Events Support Please follow the installation instructions at @@ -110,6 +146,42 @@ export default async function createPlugin( } ``` +Or, alternatively, if using the `GithubMultiOrgEntityProvider`: + +```ts title="packages/backend/src/plugins/catalog.ts" +/* highlight-add-next-line */ +import { GithubMultiOrgEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const builder = await CatalogBuilder.create(env); + + /* highlight-add-start */ + // The GitHub URL below needs to match a configured integrations.github entry + // specified in your app-config. + builder.addEntityProvider( + GithubMultiOrgEntityProvider.fromConfig(env.config, { + id: 'production', + githubUrl: 'https://github.com', + // Set the following to list the GitHub orgs you wish to ingest from. You can + // also omit this option to ingest all orgs accessible by your GitHub integration + orgs: ['org-a', 'org-b'], + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 60 }, + timeout: { minutes: 15 }, + }), + // Pass in the eventBroker to allow this provider to subscribe to GitHub events + eventBroker: env.eventBroker, + }), + ); + /* highlight-add-end */ + + // .. +} +``` + You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). The webhook will need to be configured to forward `organization`,`team` and `membership` events. diff --git a/docs/local-dev/cli-commands.md b/docs/local-dev/cli-commands.md index c4c057ffe6..66a1855fca 100644 --- a/docs/local-dev/cli-commands.md +++ b/docs/local-dev/cli-commands.md @@ -290,7 +290,8 @@ Options: --package Only load config schema that applies to the given package --lax Do not require environment variables to be set --frontend Only validate the frontend configuration - --deprecated List all deprecated configuration settings + --deprecated Output deprecated configuration settings + --strict Ensure that the provided config(s) has no errors and does not contain keys not in the schema. --config Config files to load instead of app-config.yaml (default: []) -h, --help display help for command ``` diff --git a/docs/publishing.md b/docs/publishing.md index 142e019fb2..12e4878d5a 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -11,7 +11,7 @@ npm. ### Creating a new release Releases are handled by changesets and trigger whenever the "Version Packages" -PR is merged. This is typically done every Thursday around noon CET. +PR is merged. This is typically done every Tuesday around noon CET. ## Emergency Release Process diff --git a/docs/releases/v1.13.0-changelog.md b/docs/releases/v1.13.0-changelog.md index 823ff337bc..506800eb38 100644 --- a/docs/releases/v1.13.0-changelog.md +++ b/docs/releases/v1.13.0-changelog.md @@ -4,7 +4,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. ### Patch Changes @@ -61,7 +61,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - c15e0cedbe1: The `AuthConnector` interface now supports specifying a set of scopes when refreshing a session. The `DefaultAuthConnector` implementation passes the `scope` query parameter to the auth-backend plugin appropriately. The @@ -106,7 +106,7 @@ - 67140d9f96f: Upgrade `react-virtualized-auto-sizer´ to version `^1.0.11\` - 6e0b71493df: Switched internal declaration of `DependencyGraphTypes` to use `namespace`. - c8779cc1d09: Updated `LogLine` component, which is used by the `LogViewer`, to turn URLs into clickable links. This feature is on by default -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. - 29ba8267d69: Updated dependency `@material-ui/lab` to `4.0.0-alpha.61`. - 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) @@ -170,7 +170,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. ### Patch Changes @@ -1245,7 +1245,7 @@ - d8f774c30df: Enforce the secret visibility of certificates and client secrets in the auth backend. Also, document all known options for each auth plugin. -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - 475abd1dc3f: The `microsoft` (i.e. Azure) auth provider now supports negotiating tokens for Azure resources besides Microsoft Graph (e.g. AKS, Virtual Machines, Machine diff --git a/docs/releases/v1.13.0-next.0-changelog.md b/docs/releases/v1.13.0-next.0-changelog.md index 3075d80f61..7de0a370f9 100644 --- a/docs/releases/v1.13.0-next.0-changelog.md +++ b/docs/releases/v1.13.0-next.0-changelog.md @@ -4,7 +4,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. ### Patch Changes @@ -19,7 +19,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. ### Patch Changes @@ -33,7 +33,7 @@ ### Minor Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. ### Patch Changes @@ -336,7 +336,7 @@ ### Patch Changes -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) - 7245e744ab1: Fixed the font color on `BackstageHeaderLabel` to respect the active page theme. - Updated dependencies @@ -530,7 +530,7 @@ ### Patch Changes - d8f774c30df: Enforce the secret visibility of certificates and client secrets in the auth backend. Also, document all known options for each auth plugin. -- 7908d72e033: Introduce a new global config parameter, `auth.enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. +- 7908d72e033: Introduce a new global config parameter, `enableExperimentalRedirectFlow`. When enabled, auth will happen with an in-window redirect flow rather than through a popup window. - Updated dependencies - @backstage/backend-common@0.18.4-next.0 - @backstage/config@1.0.7 diff --git a/docs/releases/v1.13.0.md b/docs/releases/v1.13.0.md index 99253ac3d2..c8803453d4 100644 --- a/docs/releases/v1.13.0.md +++ b/docs/releases/v1.13.0.md @@ -86,7 +86,7 @@ Contributed by [@sennyeya](https://github.com/sennyeya) in [#15667](https://gith ### Experimental inline auth flows -There’s new support for running auth flows inline in the current page instead of in a separate popup window, enabled via the `auth.enableExperimentalRedirectFlow` app-config parameter. This will allow the use of some providers that do not support popup flows. It’s still an experimental feature, but do try it out if this applies to you! +There’s new support for running auth flows inline in the current page instead of in a separate popup window, enabled via the `enableExperimentalRedirectFlow` app-config parameter. This will allow the use of some providers that do not support popup flows. It’s still an experimental feature, but do try it out if this applies to you! Contributed by [@headphonejames](https://github.com/headphonejames) in [#15841](https://github.com/backstage/backstage/pull/15841) diff --git a/docs/releases/v1.14.0-changelog.md b/docs/releases/v1.14.0-changelog.md new file mode 100644 index 0000000000..eae0d82e71 --- /dev/null +++ b/docs/releases/v1.14.0-changelog.md @@ -0,0 +1,2795 @@ +# Release v1.14.0 + +## @backstage/config-loader@1.3.0 + +### Minor Changes + +- 201206132da: Introduced a new config source system to replace `loadConfig`. There is a new `ConfigSource` interface along with utilities provided by `ConfigSources`, as well as a number of built-in configuration source implementations. The new system is more flexible and makes it easier to create new and reusable sources of configuration, such as loading configuration from secret providers. + + The following is an example of how to load configuration using the default behavior: + + ```ts + const source = ConfigSources.default({ + argv: options?.argv, + remote: options?.remote, + }); + const config = await ConfigSources.toConfig(source); + ``` + + The `ConfigSource` interface looks like this: + + ```ts + export interface ConfigSource { + readConfigData(options?: ReadConfigDataOptions): AsyncConfigSourceIterator; + } + ``` + + It is best implemented using an async iterator: + + ```ts + class MyConfigSource implements ConfigSource { + async *readConfigData() { + yield { + config: [ + { + context: 'example', + data: { backend: { baseUrl: 'http://localhost' } }, + }, + ], + }; + } + } + ``` + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- 473db605a4f: Added a new `noUndeclaredProperties` option to `SchemaLoader` to support enforcing that there are no extra keys when verifying config. +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/core-app-api@1.8.0 + +### Minor Changes + +- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event + +### Patch Changes + +- b645d70034a: Fixed a bug in the Azure auth provider which prevented getting access tokens with multiple scopes for one resource +- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## @backstage/repo-tools@0.3.0 + +### Minor Changes + +- 799c33047ed: **BREAKING**: The OpenAPI commands are now found within the `schema openapi` sub-command. For example `yarn backstage-repo-tools schema:openapi:verify` is now `yarn backstage-repo-tools schema openapi verify`. +- 27956d78671: Generated OpenAPI files now have a `.generated.ts` file name and a warning header at the top, to highlight that they should not be edited by hand. + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/cli-node@0.1.0 + - @backstage/errors@1.1.5 + +## @backstage/theme@0.3.0 + +### Minor Changes + +- 98c0c199b15: Updates light theme's primary foreground and `running` status indicator colours to meet WCAG. Previously #2E77D0 changed to #1F5493. + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style + +## @backstage/plugin-adr@0.6.0 + +### Minor Changes + +- b12cd5dc221: render SupportButton only if config is set + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-adr-common@0.2.9 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-analytics-module-ga4@0.1.0 + +### Minor Changes + +- 22b46f7f562: Plugin provides Backstage Analytics API for Google Analytics 4. Once installed and configured, analytics events will be sent to GA4 as your users navigate and use your Backstage instance + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-azure-devops@0.3.0 + +### Minor Changes + +- 877df261085: The getBuildRuns function now checks contains multiple comma-separated builds and splits them to send multiple requests for each and concatenates the results. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-badges-backend@0.2.0 + +### Minor Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +### Patch Changes + +- 0cd552c28d8: Removed some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-catalog@1.11.0 + +### Minor Changes + +- 2258dcae970: Added an entity namespace filter and column on the default catalog page. + + If you have a custom version of the catalog page, you can add this filter in your CatalogPage code: + + ```ts + + + + + + /* if you want namespace picker */ + + + + + + + ``` + + The namespace column can be added using `createNamespaceColumn();`. This is only needed if you customized the columns for CatalogTable. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-catalog-backend-module-aws@0.2.0 + +### Minor Changes + +- 1a3b5f1e390: **BREAKING**: AwsOrganizationCloudAccountProcessor.fromConfig now returns a promise instead of the instance directly. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-backend-module-github@0.3.0 + +### Minor Changes + +- 970678adbe2: Implement events support for `GithubMultiOrgEntityProvider` + + **BREAKING:** Passing in a custom `teamTransformer` will now correctly completely override the default transformer behavior + +### Patch Changes + +- 78bb674a713: Fixed bug in queryWithPaging that caused secondary rate limit errors in GitHub with organizations having more than 1000 repositories. This change makes one request per second to avoid concurrency issues. +- bd101cefd37: Updated the `team.edited` event emitted from `GithubOrgEntityProvider` to also include teams description. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-catalog-react@1.6.0 + +### Minor Changes + +- 2258dcae970: Added an entity namespace filter and column on the default catalog page. + + If you have a custom version of the catalog page, you can add this filter in your CatalogPage code: + + ```ts + + + + + + /* if you want namespace picker */ + + + + + + + ``` + + The namespace column can be added using `createNamespaceColumn();`. This is only needed if you customized the columns for CatalogTable. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-devtools@0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0 + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-devtools-backend@0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0 + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-devtools-common@0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.0 + +### Minor Changes + +- 2c5661f3899: Allow endpoint configuration for sqs, enabling use of localstack for testing. + +### Patch Changes + +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-jenkins@0.8.0 + +### Minor Changes + +- cf95c5137c9: Updated rebuild to use Jenkins API replay build, which works for Jenkins jobs that have required parameters. Jenkins SDK could not be used for this request because it does not have support for replay. + + Added link to view build in Jenkins CI/CD table action column. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-jenkins-common@0.1.15 + +## @backstage/plugin-jenkins-backend@0.2.0 + +### Minor Changes + +- cf95c5137c9: Updated rebuild to use Jenkins API replay build, which works for Jenkins jobs that have required parameters. Jenkins SDK could not be used for this request because it does not have support for replay. + + Added link to view build in Jenkins CI/CD table action column. + +### Patch Changes + +- 670a2dd6f4e: Fix handling of slashes in branch names +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-jenkins-common@0.1.15 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-kubernetes@0.9.0 + +### Minor Changes + +- 280ec10c18e: Added Pod logs components for Kubernetes plugin + + **BREAKING**: `kubernetesProxyApi` for custom plugins built with components from the Kubernetes plugin apis, `kubernetesProxyApi` should be added to the plugin's API list. + + ... + export const kubernetesPlugin = createPlugin({ + id: 'kubernetes', + apis: [ + ... + createApiFactory({ + api: kubernetesProxyApiRef, + deps: { + kubernetesApi: kubernetesApiRef, + }, + factory: ({ kubernetesApi }) => + new KubernetesProxyClient({ + kubernetesApi, + }), + }), + + **BREAKING**: `KubernetesDrawer` is now called `KubernetesStructuredMetadataTableDrawer` so that we can do more than just show `StructuredMetadataTable` + + `import { KubernetesDrawer } from "@backstage/plugin-kubernetes"` + + should now be: + + `import { KubernetesStructuredMetadataTableDrawer } from "@backstage/plugin-kubernetes"` + +### Patch Changes + +- c7bad1005ba: The Kubernetes plugin now requests AKS access tokens from Azure when retrieving + objects from clusters configured with `authProvider: aks` and sets `auth.aks` in + its request bodies appropriately. +- a160e02c3d7: Omit managed fields in the Kubernetes resource YAML display. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-kubernetes-backend@0.11.0 + +### Minor Changes + +- f4114f02d49: Allow fetching pod metrics limited by a `labelSelector`. + + This is used by the Kubernetes tab on a components' page and leads to much smaller responses being received from Kubernetes, especially with larger Kubernetes clusters. + +- 890988341e9: Update `aws-sdk` client from v2 to v3. + + **BREAKING**: The `AwsIamKubernetesAuthTranslator` class no longer exposes the following methods `awsGetCredentials`, `getBearerToken`, `getCredentials` and `validCredentials`. There is no replacement for these methods. + +### Patch Changes + +- 05f1d74539d: Kubernetes clusters now support `authProvider: aks`. When configured this way, + the `retrieveObjectsByServiceId` action will use the `auth.aks` value in the + request body as a bearer token to authenticate with Kubernetes. +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- a341129b754: Fixed a bug in the Kubernetes proxy endpoint where requests to clusters configured with client-side auth providers would always fail with a 500 status. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-octopus-deploy@0.2.0 + +### Minor Changes + +- 87211bc2873: Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102. + Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-scaffolder-backend@1.14.0 + +### Minor Changes + +- 67115f532b8: Expose both types of scaffolder permissions and rules through the metadata endpoint. + + The metadata endpoint now correctly exposes both types of scaffolder permissions and rules (for both the template and action resource types) through the metadata endpoint. + +- a73b3c0b097: Add ability to use `defaultNamespace` and `defaultKind` for scaffolder action `catalog:fetch` + +### Patch Changes + +- 1a48b84901c: Bump minimum required version of `vm2` to be 3.9.18 +- d20c87966a4: Bump minimum required version of `vm2` to be 3.9.17 +- 6d954de4b06: Update typing for `RouterOptions::actions` and `ScaffolderActionsExtensionPoint::addActions` to allow any kind of action being assigned to it. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.0 + +### Minor Changes + +- 439e2986be1: Add a new scaffolder action for gitlab to ensure a group exists + +### Patch Changes + +- f1496d4ab6f: Fix input schema validation issue for gitlab actions: + + - gitlab:group:ensureExists + - gitlab:projectAccessToken:create + - gitlab:projectDeployToken:create + - gitlab:projectVariable:create + +- Updated dependencies + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-scaffolder-common@1.3.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates +- 67115f532b8: Expose scaffolder permissions in new sub-aggregations. + + In addition to exporting a list of all scaffolder permissions in `scaffolderPermissions`, scaffolder-common now exports `scaffolderTemplatePermissions` and `scaffolderActionPermissions`, which contain subsets of the scaffolder permissions separated by resource type. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-scaffolder-react@1.4.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + +### Patch Changes + +- ad1a1429de4: Improvements to the `scaffolder/next` buttons UX: + + - Added padding around the "Create" button in the `Stepper` component + - Added a button bar that includes the "Cancel" and "Start Over" buttons to the `OngoingTask` component. The state of these buttons match their existing counter parts in the Context Menu + - Added a "Show Button Bar"/"Hide Button Bar" item to the `ContextMenu` component + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## @backstage/plugin-search@1.3.0 + +### Minor Changes + +- 750e45539ad: Add close button & improve search input. + + MUI's Paper wrapping the SearchBar in the SearchPage was removed, we recommend users update their apps accordingly. + + SearchBarBase's TextField's label support added & aria-label uses label string if present, tests relying on the default placeholder value should still work unless custom placeholder was given. + +### Patch Changes + +- 0e3d8d69318: Fixed 404 Error when fetching search results due to URL encoding changes +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.0 + +### Minor Changes + +- 3d72bdb41c7: Upgrade to aws-sdk v3 and include OpenSearch Serverless support + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-react@1.6.0 + +### Minor Changes + +- 750e45539ad: Add close button & improve search input. + + MUI's Paper wrapping the SearchBar in the SearchPage was removed, we recommend users update their apps accordingly. + + SearchBarBase's TextField's label support added & aria-label uses label string if present, tests relying on the default placeholder value should still work unless custom placeholder was given. + +- 1ce7f84b2e8: accepts InputProp property that can override keys from default + +### Patch Changes + +- f785f0804cd: `SearchPagination` now automatically resets the page cursor when the page limit is changed +- adb31096bc2: Fix text-overflow UI issue for Lifecycle spans in SearchFilter checkbox labels. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/app-defaults@1.3.1 + +### Patch Changes + +- 575d9178eff: Added a System Icon for resource entities. + This can be obtained using: + + ```ts + useApp().getSystemIcon('kind:resource'); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/backend-app-api@0.4.3 + +### Patch Changes + +- cf13b482f9e: Switch `configServiceFactory` to use `ConfigSources` from `@backstage/config-loader` to load config. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/backend-common@0.18.5 + +### Patch Changes + +- 0297f7a54af: Remove the direct dependency on deprecated "request" library +- 284db225083: Updated the `DatabaseManager` to include the plugin id in the Postgres application name of the database connections created for each plugin. +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- 42d817e76ab: Added `HostDiscovery` to supersede deprecated `SingleHostDiscovery` (deprecated due to name) +- Updated dependencies + - @backstage/config-loader@1.3.0 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/backend-app-api@0.4.3 + - @backstage/backend-dev-utils@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/backend-defaults@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-app-api@0.4.3 + - @backstage/backend-plugin-api@0.5.2 + +## @backstage/backend-openapi-utils@0.0.2 + +### Patch Changes + +- fe16bd39e83: Use permalinks for links including a line number reference +- 27956d78671: Adjusted README accordingly after the generated output now has a `.generated.ts` extension +- 021cfbb5152: Corrected resolution of parameter nested schema to use central schemas. +- 799c33047ed: Updated README to reflect changes in `@backstage/repo-tools`. + +## @backstage/backend-plugin-api@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/backend-tasks@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/backend-test-utils@0.1.37 + +### Patch Changes + +- 63af7f6d53f: Allow specifying custom Docker registry for database tests +- b1eb268bf9d: Added `POSTGRES_11` and `POSTGRES_12` as supported test database IDs. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-app-api@0.4.3 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## @backstage/cli@0.22.7 + +### Patch Changes + +- 473db605a4f: Enable strict config checking during `backstage-cli config:check` with the new `--strict` option which will surface schema errors. +- d548886872d: Deprecated the use of React 16 +- Updated dependencies + - @backstage/config-loader@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/cli-node@0.1.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/eslint-plugin@0.1.3 + - @backstage/release-manifests@0.0.9 + - @backstage/types@1.0.2 + +## @backstage/core-components@0.13.1 + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style +- e97769f7c0b: Fix accessibility issue on controlled select input on tab navigation + keyboard enter/space action. +- b1f13cb38aa: Fix accessibility issue with Edit Metadata Link on screen readers missing notice about opening in a new tab. +- 26cff1a5dfb: Start capturing sidebar click events in analytics by default. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/version-bridge@1.0.4 + +## @backstage/create-app@0.5.1 + +### Patch Changes + +- 1d5e42655cd: Correct command to create new plugins +- e04bb20bdc4: Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.12 + +## @backstage/dev-utils@1.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/app-defaults@1.3.1 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/test-utils@1.3.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/integration@1.4.5 + +### Patch Changes + +- b026275bcc8: Fixed a bug where the wrong credentials would be selected when using multiple GitHub app integrations. +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/integration-aws-node@0.1.3 + +### Patch Changes + +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/integration-react@1.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @techdocs/cli@1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## @backstage/test-utils@1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-app-api@1.8.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-adr-backend@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-adr-common@0.2.9 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-adr-common@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.5 + - @backstage/catalog-model@1.3.0 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-airbrake@0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/dev-utils@1.0.15 + - @backstage/test-utils@1.3.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-airbrake-backend@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + +## @backstage/plugin-allure@0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-analytics-module-ga@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-apache-airflow@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-api-docs@0.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-apollo-explorer@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-app-backend@0.3.45 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## @backstage/plugin-auth-backend@0.18.3 + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- 473db605a4f: Fix config schema definition. +- 3ffcdac7d07: Added a persistent session store through the database +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-auth-node@0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-azure-devops-backend@0.3.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-sites@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-azure-sites-backend@0.1.7 + +### Patch Changes + +- d66d4f916aa: Updated URL to `/health` and corrected typos in the `README.md` +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-badges@0.2.42 + +### Patch Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-bazaar@0.2.8 + +### Patch Changes + +- 900880ab7c3: Fixed `validateDOMNesting` warnings +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/cli@0.22.7 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-bazaar-backend@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-bitbucket-cloud-common@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.5 + +## @backstage/plugin-bitrise@0.1.45 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog-backend@1.9.1 + +### Patch Changes + +- ce8d203235b: Ensure that entity cache state is only written to the database when actually changed +- 485a6c5f7b5: Internal refactoring for performance in the service handlers +- 3587a968dcd: Fixed a bug in the `queryEntities` endpoint that was causing filtered entities to be included in cursor requests. +- ce335df9d1c: Improve the query for orphan pruning +- 27956d78671: Adjusted the OpenAPI schema file name according to the new structure +- 51064e6e5ee: Change orphan cleanup task to only log a message if it deleted entities. +- 12a345317ab: Remove unnecessary join in the entity facets endpoint, exclude nulls +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/plugin-search-backend-module-catalog@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-catalog-backend-module-azure@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.6 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-bitbucket-cloud-common@0.2.6 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-catalog-backend-module-gitlab@0.2.1 + +### Patch Changes + +- b12c41fafc4: Fix a corner case where returned users are null for bots +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-events-node@0.2.6 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.11 + +### Patch Changes + +- accaceadffa: Fixed bug in `jsonSchemaRefPlaceholderResolver` where relative $ref files were resolved through file system instead of base URL of file +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.2 + +### Patch Changes + +- 95b2168d71b: Fixes import paths and updates documentation +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-graph@0.2.30 + +### Patch Changes + +- d446f8fb0a8: Expose all `EntityRelationsGraphProps` to Catalog Graph Page +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog-import@0.9.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-catalog-node@1.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-cicd-statistics@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cicd-statistics@0.1.20 + +## @backstage/plugin-circleci@0.3.18 + +### Patch Changes + +- 451b3cadb3d: Fixes row display for in progress jobs to not display trailing "took" +- 1c4958d905f: Hide empty time field data for queued builds which haven't started yet +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-cloudbuild@0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-code-climate@0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-code-coverage@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-code-coverage-backend@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-codescene@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-config-schema@0.1.41 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-cost-insights@0.12.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-dynatrace@5.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-entity-feedback@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-entity-feedback-common@0.1.1 + +## @backstage/plugin-entity-feedback-backend@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-entity-feedback-common@0.1.1 + +## @backstage/plugin-entity-validation@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + +## @backstage/plugin-events-backend@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-module-azure@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-module-gerrit@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-module-github@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-module-gitlab@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-backend-test-utils@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.6 + +## @backstage/plugin-events-node@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + +## @backstage/plugin-explore@0.4.3 + +### Patch Changes + +- 1996920782b: Make sure that the first support button row does not break across lines +- 4851581deb6: Display the title of the entity on the explore card if present, otherwise stick to the name +- a6025e25d99: Updated the example code in the "Customization" section of the README to make the imports match the components used. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.28 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-explore-backend@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-search-backend-module-explore@0.1.1 + - @backstage/config@1.0.7 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-firehydrant@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-fossa@0.2.50 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-gcalendar@0.3.14 + +### Patch Changes + +- f493ccb9589: Pass user info email scope on auth refresh to resolve invalid credentials error +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-gcp-projects@0.3.37 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-git-release-manager@0.3.31 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-actions@0.5.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-deployments@0.1.49 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-github-issues@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-github-pull-requests-board@0.1.12 + +### Patch Changes + +- cf125c36569: The `EntityTeamPullRequestsContent` and `EntityTeamPullRequestsCard` support the ability to view the labels/tags added to each PR +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gitops-profiles@0.3.36 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gocd@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-graphiql@0.2.50 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-graphql-backend@0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-graphql@0.3.20 + +## @backstage/plugin-graphql-voyager@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-home@0.5.2 + +### Patch Changes + +- acca8966465: Remove object-hash dependency +- 957cd9b8958: Use the semantic time tag for rendering world clocks on homepage headers. +- 0e19e7b0f3a: Bump to using the later v5 versions of `@rjsf/*` +- 5272cfabc3b: Add missing @rjsf/core dependency +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-ilert@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-kafka@0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-kafka-backend@0.2.38 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-kubernetes-common@0.6.3 + +### Patch Changes + +- 05f1d74539d: AKS access tokens can now be sent over the wire to the Kubernetes backend. +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-lighthouse@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-lighthouse-common@0.1.1 + +## @backstage/plugin-lighthouse-backend@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-lighthouse-common@0.1.1 + +## @backstage/plugin-linguist@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-linguist-common@0.1.0 + +## @backstage/plugin-linguist-backend@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-linguist-common@0.1.0 + +## @backstage/plugin-microsoft-calendar@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-newrelic@0.3.36 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-newrelic-dashboard@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-org@0.6.8 + +### Patch Changes + +- 6e387c077a4: Changed the MembersListCard component to allow displaying aggregated members when viewing a group. Now, a toggle switch can be displayed that lets you switch between showing direct members and aggregated members. + + To enable this new feature, set the showAggregateMembersToggle prop on EntityMembersListCard: + + ```jsx + // In packages/app/src/components/catalog/EntityPage.tsx + const groupPage = ( + // ... + + // ... + ); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-org-react@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-pagerduty@0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-periskop@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-periskop-backend@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-permission-backend@0.5.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-permission-node@0.7.8 + +### Patch Changes + +- a788e715cfc: `createPermissionIntegrationRouter` now accepts rules and permissions for multiple resource types. Example: + + ```typescript + createPermissionIntegrationRouter({ + resources: [ + { + resourceType: 'resourceType-1', + permissions: permissionsResourceType1, + rules: rulesResourceType1, + }, + { + resourceType: 'resourceType-2', + permissions: permissionsResourceType2, + rules: rulesResourceType2, + }, + ], + }); + ``` + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + +## @backstage/plugin-playlist@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + - @backstage/plugin-playlist-common@0.1.6 + +## @backstage/plugin-playlist-backend@0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-playlist-common@0.1.6 + +## @backstage/plugin-proxy-backend@0.2.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-puppetdb@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-rollbar@0.4.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-rollbar-backend@0.1.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder@1.13.1 + +### Patch Changes + +- d560d457c98: Fix case GitLab workspace is a nested subgroup + +- ad1a1429de4: Improvements to the `scaffolder/next` buttons UX: + + - Added padding around the "Create" button in the `Stepper` component + - Added a button bar that includes the "Cancel" and "Start Over" buttons to the `OngoingTask` component. The state of these buttons match their existing counter parts in the Context Menu + - Added a "Show Button Bar"/"Hide Button Bar" item to the `ContextMenu` component + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-scaffolder-react@1.4.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.1.2 + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-node@0.1.3 + +### Patch Changes + +- 6d954de4b06: Update typing for `RouterOptions::actions` and `ScaffolderActionsExtensionPoint::addActions` to allow any kind of action being assigned to it. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/types@1.0.2 + +## @backstage/plugin-search-backend@1.3.1 + +### Patch Changes + +- 021cfbb5152: Added an OpenAPI 3.0 spec and enforced schema-first model on the router. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-module-catalog@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-module-explore@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-module-pg@0.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-module-techdocs@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-search-backend-node@1.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-sentry@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-shortcuts@0.3.10 + +### Patch Changes + +- 8a7174e297c: Marked `LocalStoredShortcuts` as deprecated, replacing it with `DefaultShortcutsApi` whose naming more clearly suggests that the shortcuts aren't necessarily stored locally (it depends on the storage implementation). +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + +## @backstage/plugin-sonarqube@0.6.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-sonarqube-react@0.1.5 + +## @backstage/plugin-sonarqube-backend@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-splunk-on-call@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-stack-overflow@0.1.15 + +### Patch Changes + +- c1ff65f315a: StackOverflowSearchResultListItem can now accept an empty result prop so that it can be rendered in the suggested SearchResultListItem pattern. +- Updated dependencies + - @backstage/plugin-home@0.5.2 + - @backstage/theme@0.3.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-stack-overflow-backend@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-stackstorm@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-tech-insights@0.3.10 + +### Patch Changes + +- 22963209d23: Added the possibility to customize the check description in the scorecard component. + + - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. + + Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. + As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-insights-backend@0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-insights-node@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-radar@0.6.4 + +### Patch Changes + +- be4fa53fab8: Fix description links when clicking entry in radar. +- Added the ability to display a timeline to each entry in the details box +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs@1.6.2 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-app-api@1.8.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/test-utils@1.3.1 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs-backend@1.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.13 + +### Patch Changes + +- 6afc7f052ca: Show cursor pointer when hovering on lightbox +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs-node@1.7.1 + +### Patch Changes + +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## @backstage/plugin-techdocs-react@1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/version-bridge@1.0.4 + +## @backstage/plugin-todo@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-todo-backend@0.1.42 + +### Patch Changes + +- 901f1ada325: Added OpenAPI schema +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-user-settings@0.7.3 + +### Patch Changes + +- 473db605a4f: Fix config schema definition. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-user-settings-backend@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## @backstage/plugin-vault@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## @backstage/plugin-vault-backend@0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## @backstage/plugin-xcmetrics@0.2.38 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## example-app@0.2.83 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-tech-insights@0.3.10 + - @backstage/plugin-scaffolder@1.13.1 + - @backstage/plugin-devtools@0.1.0 + - @backstage/plugin-kubernetes@0.9.0 + - @backstage/plugin-search@1.3.0 + - @backstage/plugin-home@0.5.2 + - @backstage/plugin-explore@0.4.3 + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/app-defaults@1.3.1 + - @backstage/plugin-badges@0.2.42 + - @backstage/plugin-tech-radar@0.6.4 + - @backstage/cli@0.22.7 + - @backstage/plugin-stack-overflow@0.1.15 + - @backstage/plugin-gcalendar@0.3.14 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-app-api@1.8.0 + - @backstage/plugin-scaffolder-react@1.4.0 + - @backstage/plugin-catalog-graph@0.2.30 + - @backstage/plugin-circleci@0.3.18 + - @backstage/plugin-search-react@1.6.0 + - @backstage/plugin-org@0.6.8 + - @backstage/core-components@0.13.1 + - @backstage/plugin-azure-devops@0.3.0 + - @backstage/plugin-jenkins@0.8.0 + - @backstage/plugin-octopus-deploy@0.2.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.13 + - @backstage/plugin-user-settings@0.7.3 + - @backstage/plugin-shortcuts@0.3.10 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-airbrake@0.3.18 + - @backstage/plugin-api-docs@0.9.3 + - @backstage/plugin-azure-sites@0.1.7 + - @backstage/plugin-cloudbuild@0.3.18 + - @backstage/plugin-code-coverage@0.2.11 + - @backstage/plugin-cost-insights@0.12.7 + - @backstage/plugin-dynatrace@5.0.0 + - @backstage/plugin-entity-feedback@0.2.1 + - @backstage/plugin-gcp-projects@0.3.37 + - @backstage/plugin-github-actions@0.5.18 + - @backstage/plugin-gocd@0.1.24 + - @backstage/plugin-graphiql@0.2.50 + - @backstage/plugin-kafka@0.3.18 + - @backstage/plugin-lighthouse@0.4.3 + - @backstage/plugin-linguist@0.1.3 + - @backstage/plugin-microsoft-calendar@0.1.3 + - @backstage/plugin-newrelic@0.3.36 + - @backstage/plugin-pagerduty@0.5.11 + - @backstage/plugin-playlist@0.1.9 + - @backstage/plugin-puppetdb@0.1.1 + - @backstage/plugin-rollbar@0.4.18 + - @backstage/plugin-sentry@0.5.3 + - @backstage/plugin-stackstorm@0.1.2 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/plugin-todo@0.2.20 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-apache-airflow@0.2.11 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-catalog-import@0.9.8 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-newrelic-dashboard@0.2.11 + - @backstage/plugin-permission-react@0.4.12 + - @backstage/plugin-search-common@1.2.3 + - @internal/plugin-catalog-customized@0.0.10 + +## example-backend@0.2.83 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/plugin-devtools-backend@0.1.0 + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/plugin-kubernetes-backend@0.11.0 + - @backstage/plugin-auth-backend@0.18.3 + - @backstage/plugin-badges-backend@0.2.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-todo-backend@0.1.42 + - @backstage/plugin-jenkins-backend@0.2.0 + - @backstage/plugin-azure-sites-backend@0.1.7 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-search-backend@1.3.1 + - example-app@0.2.83 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-app-backend@0.3.45 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/plugin-entity-feedback-backend@0.1.3 + - @backstage/plugin-events-backend@0.2.6 + - @backstage/plugin-playlist-backend@0.3.1 + - @backstage/plugin-rollbar-backend@0.1.42 + - @backstage/plugin-search-backend-module-pg@0.5.6 + - @backstage/plugin-tech-insights-backend@0.5.11 + - @backstage/plugin-techdocs-backend@1.6.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.14 + - @backstage/plugin-adr-backend@0.3.3 + - @backstage/plugin-azure-devops-backend@0.3.24 + - @backstage/plugin-code-coverage-backend@0.2.11 + - @backstage/plugin-explore-backend@0.0.7 + - @backstage/plugin-graphql-backend@0.1.35 + - @backstage/plugin-kafka-backend@0.2.38 + - @backstage/plugin-lighthouse-backend@0.2.1 + - @backstage/plugin-linguist-backend@0.2.2 + - @backstage/plugin-permission-backend@0.5.20 + - @backstage/plugin-proxy-backend@0.2.39 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.29 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## example-backend-next@0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/plugin-kubernetes-backend@0.11.0 + - @backstage/plugin-todo-backend@0.1.42 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-search-backend@1.3.1 + - @backstage/backend-defaults@0.1.10 + - @backstage/plugin-app-backend@0.3.45 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-search-backend-module-catalog@0.1.1 + - @backstage/plugin-search-backend-module-explore@0.1.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.1 + - @backstage/plugin-techdocs-backend@1.6.2 + - @backstage/plugin-permission-backend@0.5.20 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/plugin-permission-common@0.7.5 + +## e2e-test@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.1 + - @backstage/cli-common@0.1.12 + - @backstage/errors@1.1.5 + +## techdocs-cli-embedded-app@0.2.82 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/app-defaults@1.3.1 + - @backstage/cli@0.22.7 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/test-utils@1.3.1 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @internal/plugin-catalog-customized@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + +## @internal/plugin-todo-list@1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## @internal/plugin-todo-list-backend@1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 diff --git a/docs/releases/v1.14.0-next.2-changelog.md b/docs/releases/v1.14.0-next.2-changelog.md new file mode 100644 index 0000000000..95bbc63953 --- /dev/null +++ b/docs/releases/v1.14.0-next.2-changelog.md @@ -0,0 +1,1334 @@ +# Release v1.14.0-next.2 + +## @backstage/theme@0.3.0-next.0 + +### Minor Changes + +- 98c0c199b15: Updates light theme's primary foreground and `running` status indicator colours to meet WCAG. Previously #2E77D0 changed to #1F5493. + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style + +## @backstage/plugin-azure-devops@0.3.0-next.2 + +### Minor Changes + +- 877df261085: The getBuildRuns function now checks contains multiple comma-separated builds and splits them to send multiple requests for each and concatenates the results. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-badges-backend@0.2.0-next.2 + +### Minor Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-backend-module-github@0.3.0-next.2 + +### Minor Changes + +- 970678adbe2: Implement events support for `GithubMultiOrgEntityProvider` + + **BREAKING:** Passing in a custom `teamTransformer` will now correctly completely override the default transformer behavior + +### Patch Changes + +- bd101cefd37: Updated the `team.edited` event emitted from `GithubOrgEntityProvider` to also include teams description. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-devtools@0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0-next.0 + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-devtools-backend@0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0-next.0 + - @backstage/config@1.0.7 + +## @backstage/plugin-devtools-common@0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.0-next.2 + +### Minor Changes + +- 2c5661f3899: Allow endpoint configuration for sqs, enabling use of localstack for testing. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.0-next.2 + +### Minor Changes + +- 439e2986be1: Add a new scaffolder action for gitlab to ensure a group exists + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-common@1.3.0-next.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + +## @backstage/plugin-scaffolder-react@1.4.0-next.2 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.0-next.2 + +### Minor Changes + +- 3d72bdb41c7: Upgrade to aws-sdk v3 and include OpenSearch Serverless support + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/integration-aws-node@0.1.2 + +## @backstage/plugin-search-react@1.6.0-next.2 + +### Minor Changes + +- 1ce7f84b2e8: accepts InputProp property that can override keys from default + +### Patch Changes + +- adb31096bc2: Fix text-overflow UI issue for Lifecycle spans in SearchFilter checkbox labels. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/app-defaults@1.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/backend-openapi-utils@0.0.2-next.1 + +### Patch Changes + +- fe16bd39e83: Use permalinks for links including a line number reference +- 021cfbb5152: Corrected resolution of parameter nested schema to use central schemas. + +## @backstage/core-components@0.13.1-next.1 + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style +- e97769f7c0b: Fix accessibility issue on controlled select input on tab navigation + keyboard enter/space action. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/create-app@0.5.1-next.2 + +### Patch Changes + +- 1d5e42655cd: Correct command to create new plugins + +## @backstage/dev-utils@1.0.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/app-defaults@1.3.1-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/integration-react@1.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/test-utils@1.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-adr@0.5.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-airbrake@0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/dev-utils@1.0.15-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-allure@0.1.34-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-analytics-module-ga@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-analytics-module-ga4@0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-apache-airflow@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-api-docs@0.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-apollo-explorer@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-auth-backend@0.18.3-next.2 + +### Patch Changes + +- 3ffcdac7d07: Added a persistent session store through the database +- Updated dependencies + - @backstage/config@1.0.7 + +## @backstage/plugin-azure-sites@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-badges@0.2.42-next.2 + +### Patch Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-bazaar@0.2.8-next.2 + +### Patch Changes + +- 900880ab7c3: Fixed `validateDOMNesting` warnings +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/cli@0.22.7-next.0 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-bitrise@0.1.45-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog@1.11.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog-backend@1.9.1-next.2 + +### Patch Changes + +- ce8d203235b: Ensure that entity cache state is only written to the database when actually changed +- 485a6c5f7b5: Internal refactoring for performance in the service handlers +- 3587a968dcd: Fixed a bug in the `queryEntities` endpoint that was causing filtered entities to be included in cursor requests. +- 12a345317ab: Remove unnecessary join in the entity facets endpoint, exclude nulls +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-backend-module-aws@0.1.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.11-next.2 + +### Patch Changes + +- accaceadffa: Fixed bug in `jsonSchemaRefPlaceholderResolver` where relative $ref files were resolved through file system instead of base URL of file +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.2-next.2 + +### Patch Changes + +- 95b2168d71b: Fixes import paths and updates documentation +- Updated dependencies + - @backstage/config@1.0.7 + +## @backstage/plugin-catalog-graph@0.2.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog-import@0.9.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-catalog-react@1.6.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-cicd-statistics@0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cicd-statistics@0.1.20-next.2 + +## @backstage/plugin-circleci@0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-cloudbuild@0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-code-climate@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-code-coverage@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-codescene@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-config-schema@0.1.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-cost-insights@0.12.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-dynatrace@5.0.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-entity-feedback@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-entity-validation@0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-explore@0.4.3-next.2 + +### Patch Changes + +- 4851581deb6: Display the title of the entity on the explore card if present, otherwise stick to the name +- a6025e25d99: Updated the example code in the "Customization" section of the README to make the imports match the components used. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-explore-react@0.0.28 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-firehydrant@0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-fossa@0.2.50-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gcalendar@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gcp-projects@0.3.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-git-release-manager@0.3.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-actions@0.5.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-deployments@0.1.49-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-issues@0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-github-pull-requests-board@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gitops-profiles@0.3.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-gocd@0.1.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-graphiql@0.2.50-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-graphql-voyager@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-home@0.5.2-next.2 + +### Patch Changes + +- acca8966465: Remove object-hash dependency +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-ilert@0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-jenkins@0.7.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-kafka@0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-kubernetes@0.9.0-next.2 + +### Patch Changes + +- c7bad1005ba: The Kubernetes plugin now requests AKS access tokens from Azure when retrieving + objects from clusters configured with `authProvider: aks` and sets `auth.aks` in + its request bodies appropriately. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-kubernetes-backend@0.11.0-next.2 + +### Patch Changes + +- 05f1d74539d: Kubernetes clusters now support `authProvider: aks`. When configured this way, + the `retrieveObjectsByServiceId` action will use the `auth.aks` value in the + request body as a bearer token to authenticate with Kubernetes. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/config@1.0.7 + - @backstage/integration-aws-node@0.1.2 + +## @backstage/plugin-kubernetes-common@0.6.3-next.0 + +### Patch Changes + +- 05f1d74539d: AKS access tokens can now be sent over the wire to the Kubernetes backend. + +## @backstage/plugin-lighthouse@0.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-linguist@0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-microsoft-calendar@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-newrelic@0.3.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-newrelic-dashboard@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-octopus-deploy@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-org@0.6.8-next.2 + +### Patch Changes + +- 6e387c077a4: Changed the MembersListCard component to allow displaying aggregated members when viewing a group. Now, a toggle switch can be displayed that lets you switch between showing direct members and aggregated members. + + To enable this new feature, set the showAggregateMembersToggle prop on EntityMembersListCard: + + ```jsx + // In packages/app/src/components/catalog/EntityPage.tsx + const groupPage = ( + // ... + + // ... + ); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-org-react@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-pagerduty@0.5.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-periskop@0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-playlist@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-puppetdb@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-rollbar@0.4.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-scaffolder@1.13.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/plugin-scaffolder-react@1.4.0-next.2 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## @backstage/plugin-scaffolder-backend@1.13.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + +## @backstage/plugin-scaffolder-node@0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + +## @backstage/plugin-search@1.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-search-backend@1.3.1-next.2 + +### Patch Changes + +- 021cfbb5152: Added an OpenAPI 3.0 spec and enforced schema-first model on the router. +- Updated dependencies + - @backstage/config@1.0.7 + +## @backstage/plugin-sentry@0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-shortcuts@0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-sonarqube@0.6.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-splunk-on-call@0.4.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-stack-overflow@0.1.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.5.2-next.2 + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-stackstorm@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-tech-insights@0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-tech-radar@0.6.4-next.2 + +### Patch Changes + +- be4fa53fab8: Fix description links when clicking entry in radar. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs@1.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-techdocs-react@1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-todo@0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-user-settings@0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-vault@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + +## @backstage/plugin-xcmetrics@0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + +## example-app@0.2.83-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools@0.1.0-next.0 + - @backstage/plugin-kubernetes@0.9.0-next.2 + - @backstage/plugin-home@0.5.2-next.2 + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-badges@0.2.42-next.2 + - @backstage/plugin-tech-radar@0.6.4-next.2 + - @backstage/plugin-scaffolder-react@1.4.0-next.2 + - @backstage/plugin-explore@0.4.3-next.2 + - @backstage/plugin-org@0.6.8-next.2 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-azure-devops@0.3.0-next.2 + - @backstage/plugin-stack-overflow@0.1.15-next.2 + - @backstage/app-defaults@1.3.1-next.2 + - @backstage/cli@0.22.7-next.0 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-airbrake@0.3.18-next.2 + - @backstage/plugin-api-docs@0.9.3-next.2 + - @backstage/plugin-azure-sites@0.1.7-next.2 + - @backstage/plugin-catalog-graph@0.2.30-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-circleci@0.3.18-next.2 + - @backstage/plugin-cloudbuild@0.3.18-next.2 + - @backstage/plugin-code-coverage@0.2.11-next.2 + - @backstage/plugin-cost-insights@0.12.7-next.2 + - @backstage/plugin-dynatrace@5.0.0-next.2 + - @backstage/plugin-entity-feedback@0.2.1-next.2 + - @backstage/plugin-gcalendar@0.3.14-next.1 + - @backstage/plugin-gcp-projects@0.3.37-next.1 + - @backstage/plugin-github-actions@0.5.18-next.2 + - @backstage/plugin-gocd@0.1.24-next.2 + - @backstage/plugin-graphiql@0.2.50-next.1 + - @backstage/plugin-jenkins@0.7.17-next.2 + - @backstage/plugin-kafka@0.3.18-next.2 + - @backstage/plugin-lighthouse@0.4.3-next.2 + - @backstage/plugin-linguist@0.1.3-next.2 + - @backstage/plugin-microsoft-calendar@0.1.3-next.1 + - @backstage/plugin-newrelic@0.3.36-next.1 + - @backstage/plugin-octopus-deploy@0.2.0-next.2 + - @backstage/plugin-pagerduty@0.5.11-next.2 + - @backstage/plugin-playlist@0.1.9-next.2 + - @backstage/plugin-puppetdb@0.1.1-next.2 + - @backstage/plugin-rollbar@0.4.18-next.2 + - @backstage/plugin-scaffolder@1.13.1-next.2 + - @backstage/plugin-search@1.3.0-next.2 + - @backstage/plugin-sentry@0.5.3-next.2 + - @backstage/plugin-shortcuts@0.3.10-next.2 + - @backstage/plugin-stackstorm@0.1.2-next.1 + - @backstage/plugin-tech-insights@0.3.10-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.13-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/plugin-todo@0.2.20-next.2 + - @backstage/plugin-user-settings@0.7.3-next.2 + - @backstage/plugin-apache-airflow@0.2.11-next.1 + - @backstage/plugin-catalog-import@0.9.8-next.2 + - @backstage/plugin-newrelic-dashboard@0.2.11-next.2 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + - @internal/plugin-catalog-customized@0.0.10-next.2 + +## example-backend@0.2.83-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-backend@0.1.0-next.0 + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-badges-backend@0.2.0-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.0-next.2 + - @backstage/plugin-kubernetes-backend@0.11.0-next.2 + - @backstage/plugin-auth-backend@0.18.3-next.2 + - @backstage/plugin-search-backend@1.3.1-next.2 + - example-app@0.2.83-next.2 + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.14-next.2 + - @backstage/config@1.0.7 + +## example-backend-next@0.0.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-kubernetes-backend@0.11.0-next.2 + - @backstage/plugin-search-backend@1.3.1-next.2 + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + +## e2e-test@0.2.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.1-next.2 + +## techdocs-cli-embedded-app@0.2.82-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/app-defaults@1.3.1-next.2 + - @backstage/cli@0.22.7-next.0 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + +## @internal/plugin-catalog-customized@0.0.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + +## @internal/plugin-todo-list@1.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 diff --git a/docs/releases/v1.14.0.md b/docs/releases/v1.14.0.md new file mode 100644 index 0000000000..2c565e2519 --- /dev/null +++ b/docs/releases/v1.14.0.md @@ -0,0 +1,80 @@ +--- +id: v1.14.0 +title: v1.14.0 +description: Backstage Release v1.14.0 +--- + +These are the release notes for the v1.14.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for their hard work in getting this release developed and done. + +## Highlights + +This release has an important security fix, along with a lot of squashed bugs and exciting additions! Enjoy. + +### **BREAKING**: Tweaks to the OpenAPI tooling + +There’s been further work made on the OpenAPI tooling! One of the changes is that the commands for this feature are grouped under a `schema openapi` subcommand. This lets us structure things a bit better for the future. The generated file now also has a `.generated.ts` extension, to more easily be able to keep it apart in linting and similar. + +### **BREAKING**: Kubernetes plugin log viewer and tweaks + +There’s been some awesome additions made to the Kubernetes plugin, including the ability to show pod logs! To support this, some breaking changes were made in some of its interfaces. Check out [#17120](https://github.com/backstage/backstage/pull/17120) for some details of what changed. + +### **DEPRECATION**: React 16 + +We are preparing for React 18, and as part of doing that, we are now officially deprecating support for React 16. Nothing will break for you just yet, but if you are still on React 16 your `backstage-cli` commands will start to show helpful warning messages guiding you to bump to version 17 when you can. + +See [#17752](https://github.com/backstage/backstage/pull/17752) for some details about this, and links to the relevant issues. + +### New plugin: DevTools + +This plugin is focused on integrators rather than end users. It allows you to see useful information about your Backstage installation, such as what operating system and NodeJS version it’s running on, what Backstage and individual package versions you have, and more! This may serve as a foundation for adding even more ops focused features in the future. + +Contributed by [@awanlin](https://github.com/awanlin) in [#17393](https://github.com/backstage/backstage/pull/17393) + +### Migration to AWS-SDK version 3 + +There’s been work done under the hood to migrate AWS features over to using v3 of their client SDKs. While this should mostly go below the radar and ultimately work the same as it did before, do reach out to us if you encounter any problems that might be related to this migration. + +There’s actually a minor interface breakage as part of this, where `AwsIamKubernetesAuthTranslator` has some methods removed, but that’s one which may not have a lot of use outside of the package. + +Contributed by [@aochsner](https://github.com/aochsner), see PRs linked at the bottom of issue [#16470](https://github.com/backstage/backstage/issues/16470) + +### Persistent session store for the auth backend + +For auth providers that use session storage, those sessions are now persisted in the auth backend database, instead of in local memory. This should make session handling work better across scaled auth backend instances. + +### Markdown Output Support for Software Templates + +You can now output Markdown from the Software Template runs which can provide more data to the end user after a job has completed in the outputs section of `scaffolder/next` + +Contributed by [@voximity](https://github.com/voximity) in [#17641](https://github.com/backstage/backstage/pull/17641) + +### Refactored Configuration Loading + +The configuration loading system has been refactored to make it easier to extend the system with additional sources of configuration. See the [initial PR](https://github.com/backstage/backstage/pull/17209) and the [`@backstage/config-loader` changelog](https://github.com/backstage/backstage/blob/master/packages/config-loader/CHANGELOG.md#130) for more details. + +### Catalog database performance tweaks + +We found some hotspots in the catalog database operations, and streamlined them. Hopefully this should be noticeable in the form of slightly lower CPU and IOPS usage. + +## Security Fixes + +A [security flaw in the `vm2` package](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32314) used by the Scaffolder plugin was patched by our automated security processes in [#17810](https://github.com/backstage/backstage/pull/17810). The fixed version of `vm2` was already covered by the required version range of the Scaffolder plugin, so adopters are able to address this vulnerability separately without upgrading Backstage itself, as part of their regular security processes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.14.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md index b87a77f4ed..87afabda60 100644 --- a/docs/tutorials/switching-sqlite-postgres.md +++ b/docs/tutorials/switching-sqlite-postgres.md @@ -37,7 +37,7 @@ backend: connection: ':memory:' # highlight-remove-end # highlight-add-start - # config options: https://node-postgres.com/api/client + # config options: https://node-postgres.com/apis/client client: pg connection: host: ${POSTGRES_HOST} @@ -72,7 +72,7 @@ backend: connection: ':memory:' # highlight-remove-end # highlight-add-start - # config options: https://node-postgres.com/api/client + # config options: https://node-postgres.com/apis/client client: pg connection: host: ${POSTGRES_HOST} diff --git a/microsite/data/plugins/3scale.yaml b/microsite/data/plugins/3scale.yaml new file mode 100644 index 0000000000..c190ed7e9e --- /dev/null +++ b/microsite/data/plugins/3scale.yaml @@ -0,0 +1,10 @@ +--- +title: APIs with 3scale +author: Red Hat +authorUrl: https://redhat.com +category: Discovery +description: Synchronize 3scale content into the Backstage catalog. +documentation: https://janus-idp.io/plugins/3scale +iconUrl: http://janus-idp.io/images/plugins/3scale.svg +npmPackageName: '@janus-idp/backstage-plugin-3scale-backend' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/aws-app-development.yaml b/microsite/data/plugins/aws-app-development.yaml new file mode 100644 index 0000000000..3944bbb4e0 --- /dev/null +++ b/microsite/data/plugins/aws-app-development.yaml @@ -0,0 +1,10 @@ +--- +title: AWS App Developer Tools +author: Amazon Web Services +authorUrl: https://aws.amazon.com/ +category: Infrastructure +description: Create and manage AWS Apps within Backstage +documentation: https://github.com/awslabs/app-development-for-backstage-io-on-aws#readme +iconUrl: https://github.com/awslabs/app-development-for-backstage-io-on-aws/blob/main/docs/images/AWS_logo.png?raw=true +npmPackageName: '@aws/plugin-aws-apps-for-backstage' +addedDate: '2023-05-10' diff --git a/microsite/data/plugins/dependencytrack b/microsite/data/plugins/dependencytrack.yaml similarity index 100% rename from microsite/data/plugins/dependencytrack rename to microsite/data/plugins/dependencytrack.yaml diff --git a/microsite/data/plugins/jfrog-artifactory.yaml b/microsite/data/plugins/jfrog-artifactory.yaml new file mode 100644 index 0000000000..279cbc161e --- /dev/null +++ b/microsite/data/plugins/jfrog-artifactory.yaml @@ -0,0 +1,10 @@ +--- +title: Container Image Registry for JFrog Artifactory +author: Red Hat +authorUrl: https://redhat.com +category: Image +description: View container image details from JFrog Artifactory in Backstage. +documentation: https://janus-idp.io/plugins/jfrog-artifactory +iconUrl: http://janus-idp.io/images/plugins/jfrog-artifactory.svg +npmPackageName: '@janus-idp/backstage-plugin-jfrog-artifactory' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/keycloak.yaml b/microsite/data/plugins/keycloak.yaml new file mode 100644 index 0000000000..882d43f515 --- /dev/null +++ b/microsite/data/plugins/keycloak.yaml @@ -0,0 +1,10 @@ +--- +title: Authentication and Authorization with Keycloak +author: Red Hat +authorUrl: https://redhat.com +category: Authentication +description: Load users and groups from Keycloak, enabling use of multiple authentication providers to be applied to Backstage entities. +documentation: https://janus-idp.io/plugins/keycloak +iconUrl: http://janus-idp.io/images/plugins/keycloak.svg +npmPackageName: '@janus-idp/backstage-plugin-keycloak-backend' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/ocm.yaml b/microsite/data/plugins/ocm.yaml new file mode 100644 index 0000000000..15c23a0fb7 --- /dev/null +++ b/microsite/data/plugins/ocm.yaml @@ -0,0 +1,10 @@ +--- +title: Multi Cluster View with OCM +author: Red Hat +authorUrl: https://redhat.com +category: OCM +description: View clusters from OCM's MultiClusterHub and MultiCluster Engine in Backstage. +documentation: https://janus-idp.io/plugins/ocm +iconUrl: http://janus-idp.io/images/plugins/ocm.svg +npmPackageName: '@janus-idp/backstage-plugin-ocm' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/quay.yaml b/microsite/data/plugins/quay.yaml new file mode 100644 index 0000000000..e4aeb1ec1a --- /dev/null +++ b/microsite/data/plugins/quay.yaml @@ -0,0 +1,10 @@ +--- +title: Container Image Registry for Quay +author: Red Hat +authorUrl: https://redhat.com +category: Image +description: View container image details from Quay in Backstage. +documentation: https://janus-idp.io/plugins/quay +iconUrl: http://janus-idp.io/images/plugins/quay.svg +npmPackageName: '@janus-idp/backstage-plugin-quay' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/tekton.yaml b/microsite/data/plugins/tekton.yaml new file mode 100644 index 0000000000..b1ebfb1349 --- /dev/null +++ b/microsite/data/plugins/tekton.yaml @@ -0,0 +1,10 @@ +--- +title: Pipelines with Tekton +author: Red Hat +authorUrl: https://redhat.com +category: CI +description: Easily view Tekton PipelineRun status for your services in Backstage. +documentation: https://janus-idp.io/plugins/tekton +iconUrl: http://janus-idp.io/images/plugins/tekton.svg +npmPackageName: '@janus-idp/backstage-plugin-tekton' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/topology.yaml b/microsite/data/plugins/topology.yaml new file mode 100644 index 0000000000..2f26f7c755 --- /dev/null +++ b/microsite/data/plugins/topology.yaml @@ -0,0 +1,10 @@ +--- +title: Application Topology for Kubernetes +author: Red Hat +authorUrl: https://redhat.com +category: Kubernetes +description: Visualize the deployment status and related resources of your applications deployed on any Kubernetes cluster. +documentation: https://janus-idp.io/plugins/topology +iconUrl: http://janus-idp.io/images/plugins/topology.svg +npmPackageName: '@janus-idp/backstage-plugin-topology' +addedDate: '2023-05-15' diff --git a/microsite/data/plugins/xkcd.yaml b/microsite/data/plugins/xkcd.yaml new file mode 100644 index 0000000000..370718a08f --- /dev/null +++ b/microsite/data/plugins/xkcd.yaml @@ -0,0 +1,10 @@ +--- +title: xkcd comic +author: Vity +authorUrl: https://github.com/Vity01 +category: Humor +description: xkcd comic within Backstage +documentation: https://github.com/Vity01/backstage-xkcd/ +iconUrl: https://raw.githubusercontent.com/Vity01/backstage-xkcd/main/docs/xkcd.svg +npmPackageName: 'backstage-plugin-xkcd' +addedDate: '2023-05-05' diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index e6137b572b..9985796e3f 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -173,7 +173,7 @@ module.exports = { position: 'left', }, { - to: 'docs/releases/v1.12.0', + to: 'docs/releases/v1.14.0', label: 'Releases', position: 'left', }, @@ -241,7 +241,7 @@ module.exports = { }, { label: 'Subscribe to our newsletter', - to: 'https://mailchi.mp/spotify/backstage-community', + to: 'https://info.backstage.spotify.com/newsletter_subscribe', }, { label: 'CNCF Incubation', diff --git a/microsite/package.json b/microsite/package.json index 601a234688..98301ce2d0 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -17,7 +17,7 @@ "docusaurus": "docusaurus" }, "devDependencies": { - "@docusaurus/module-type-aliases": "0.0.0-5569", + "@docusaurus/module-type-aliases": "0.0.0-5580", "@spotify/prettier-config": "^14.0.0", "@tsconfig/docusaurus": "^1.0.6", "@types/webpack-env": "^1.18.0", @@ -28,9 +28,9 @@ }, "prettier": "@spotify/prettier-config", "dependencies": { - "@docusaurus/core": "0.0.0-5569", - "@docusaurus/plugin-client-redirects": "0.0.0-5569", - "@docusaurus/preset-classic": "0.0.0-5569", + "@docusaurus/core": "0.0.0-5580", + "@docusaurus/plugin-client-redirects": "0.0.0-5580", + "@docusaurus/preset-classic": "0.0.0-5580", "@swc/core": "^1.3.46", "clsx": "^1.1.1", "docusaurus-plugin-sass": "^0.2.3", diff --git a/microsite/sidebars.json b/microsite/sidebars.json index cf2f9b7b56..e75683f803 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,7 @@ { "releases": { "Release Notes": [ + "releases/v1.14.0", "releases/v1.13.0", "releases/v1.12.0", "releases/v1.11.0", @@ -408,6 +409,7 @@ "label": "Core Services", "items": ["backend-system/core-services/index"] } - ] + ], + "Accessibility": ["accessibility/index"] } } diff --git a/microsite/src/components/pluginsFilter/pluginsFilter.tsx b/microsite/src/components/pluginsFilter/pluginsFilter.tsx new file mode 100644 index 0000000000..25c8a5ff52 --- /dev/null +++ b/microsite/src/components/pluginsFilter/pluginsFilter.tsx @@ -0,0 +1,36 @@ +import { ChipCategory } from '@site/src/util/types'; +import React from 'react'; + +type Props = { + categories: ChipCategory[]; + handleChipClick: (name: string) => void; +}; + +const PluginsFilter = ({ categories, handleChipClick }: Props) => { + return ( +
+ +
    + {categories.map(chip => { + return ( +
  • handleChipClick(chip.name)}> +
    + handleChipClick(chip.name)} + /> + {chip.name} +
    +
  • + ); + })} +
+
+ ); +}; + +export default PluginsFilter; diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 280a165daa..b1c9601110 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -1,13 +1,13 @@ import Link from '@docusaurus/Link'; import Layout from '@theme/Layout'; import clsx from 'clsx'; -import React from 'react'; - +import React, { useState } from 'react'; import { IPluginData, PluginCard } from './_pluginCard'; import pluginsStyles from './plugins.module.scss'; +import { ChipCategory } from '@site/src/util/types'; import { truncateDescription } from '@site/src/util/truncateDescription'; +import PluginsFilter from '@site/src/components/pluginsFilter/pluginsFilter'; -//#region Plugin data import const pluginsContext = require.context( '../../../data/plugins', false, @@ -29,50 +29,137 @@ const plugins = pluginsContext.keys().reduce( plugins.corePlugins.sort((a, b) => a.order - b.order); plugins.otherPlugins.sort((a, b) => a.order - b.order); -//#endregion -const Plugins = () => ( - -
-
-
-

Plugin Marketplace

+const Plugins = () => { + const allCategoriesSet = new Set( + [...plugins.corePlugins, ...plugins.otherPlugins].map( + ({ category }) => category, + ), + ); + const allCategoriesArray = Array.from(allCategoriesSet).map(category => ({ + name: category, + isSelected: false, + })); + const [categories, setCategories] = + useState(allCategoriesArray); + const [selectedCategories, setSelectedCategories] = useState([]); + const [showCoreFeatures, setShowCoreFeatures] = useState(true); + const [showOtherPlugins, setShowOtherPlugins] = useState(true); -

- Open source plugins that you can add to your Backstage deployment. - Learn how to build a plugin. -

+ const handleChipClick = (categoryName: string) => { + const isSelected = + categories.find(category => category.name === categoryName)?.isSelected || + false; + + const newSelectedCategories = isSelected + ? selectedCategories.filter(c => c !== categoryName) + : [...selectedCategories, categoryName]; + + setSelectedCategories(newSelectedCategories); + + const newCategories = categories.map(category => { + if (category.name === categoryName) { + return { ...category, isSelected: !isSelected }; + } + return category; + }); + + setCategories(newCategories); + + if (!newSelectedCategories.includes('Core Feature')) { + setShowCoreFeatures(false); + } else { + setShowCoreFeatures(true); + } + + if ( + newSelectedCategories.length === 1 && + newSelectedCategories[0] === 'Core Feature' + ) { + setShowOtherPlugins(false); + } else { + setShowOtherPlugins(true); + } + + if (newSelectedCategories.length === 0) { + setShowOtherPlugins(true); + setShowCoreFeatures(true); + } + }; + + return ( + +
+
+
+

Plugin Marketplace

+ +

+ Open source plugins that you can add to your Backstage deployment. + Learn how to build a plugin. +

+
+ + + Add to Marketplace +
- - Add to Marketplace - +
+
+ +
+ + {showCoreFeatures && ( +
+

Core Features

+
+ {plugins.corePlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
+
+ )} + + {showOtherPlugins && ( +
+

All Plugins

+
+ {plugins.otherPlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
+
+ )}
- -
- -

Core Features

- -
- {plugins.corePlugins.map(pluginData => ( - - ))} -
- -

All Plugins

- -
- {plugins.otherPlugins.map(pluginData => ( - - ))} -
-
- -); + + ); +}; export default Plugins; diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index bb08c2fd33..d5ea5de6e7 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -28,10 +28,60 @@ :global(.pluginsContainer) { gap: 1rem; display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(250px, 300px)); + } + + @media (max-width: 768px) { + :global(.pluginsContainer) { + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + } + } + + :global(.hidePluginsHeader) { + display: none; } :global(.fit-content) { width: fit-content; } + + :global(.pluginsFilterBox) { + width: 100%; + margin-bottom: 1rem; + height: 1rem; + } + + :global(.dropdown) { + float: right; + margin-bottom: 1rem; + } + + :global(.button--info) { + background-color: transparent; + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); + min-width: 250px; + } + + :global(label.dropdown__item) { + display: flex; + align-items: center; + cursor: pointer; + margin-top: 5px; + + &:hover { + background-color: var(--ifm-color-primary); + color: black; + } + } + + :global(.dropdown__label) { + font-size: 15px; + cursor: pointer; + } + + :global(.dropdown__checkbox) { + margin-right: 10px; + cursor: pointer; + } } diff --git a/microsite/src/util/types.ts b/microsite/src/util/types.ts new file mode 100644 index 0000000000..fba7c0ba46 --- /dev/null +++ b/microsite/src/util/types.ts @@ -0,0 +1,4 @@ +export type ChipCategory = { + name: string; + isSelected: boolean; +}; diff --git a/microsite/yarn.lock b/microsite/yarn.lock index c16f65240e..fe1c123575 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -1620,9 +1620,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/core@npm:0.0.0-5569" +"@docusaurus/core@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/core@npm:0.0.0-5580" dependencies: "@babel/core": ^7.20.12 "@babel/generator": ^7.21.1 @@ -1634,13 +1634,13 @@ __metadata: "@babel/runtime": ^7.21.0 "@babel/runtime-corejs3": ^7.21.0 "@babel/traverse": ^7.21.2 - "@docusaurus/cssnano-preset": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/mdx-loader": 0.0.0-5569 + "@docusaurus/cssnano-preset": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/mdx-loader": 0.0.0-5580 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 "@slorber/static-site-generator-webpack-plugin": ^4.0.7 "@svgr/webpack": ^6.5.1 autoprefixer: ^10.4.13 @@ -1700,41 +1700,41 @@ __metadata: react-dom: ^16.8.4 || ^17.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: 573746ba85750381b110a98cfb529d8c961523b735c1945016bf8f79ba2cde38d08ecda88dc1be4852d8c9a49121e23ec964b05354fd6f6d26e6f31e71f175c1 + checksum: 1160559109aa834bcd3dc0210ca824ad6cbdea363951c5cba690c1882c78a7da6e1e52b8a5c35fef3bfc23f9f66e84880c354727b7987d371cac8ec6fb77d1bb languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/cssnano-preset@npm:0.0.0-5569" +"@docusaurus/cssnano-preset@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/cssnano-preset@npm:0.0.0-5580" dependencies: cssnano-preset-advanced: ^5.3.10 postcss: ^8.4.21 postcss-sort-media-queries: ^4.3.0 tslib: ^2.5.0 - checksum: 11408a0f9eb1a4a83b2045a0172ef1fbf0523a99fa9d81a8efe9a3a968b449887616ad8d95b0abb55b2bf82a178193c20c0304942c4f2ba51b693b9209031204 + checksum: 4a46af1e9327d6ebbed3f0f6e60cc1ca59d5c07d39be35c42c13b0a64795b0b1565585adfca063798be79100aca425ee0c12f28a816b56686fb97726bec00f40 languageName: node linkType: hard -"@docusaurus/logger@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/logger@npm:0.0.0-5569" +"@docusaurus/logger@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/logger@npm:0.0.0-5580" dependencies: chalk: ^4.1.2 tslib: ^2.5.0 - checksum: 26be75d7180d9b9d525ce5014e1e24c69fd54d1707cabc5acc76b47e3282cfb185613fb4d27f32b5cced92fe80384c68e2d991cf4cabbecca331f570c3e10d9b + checksum: 5792b6672623b70d38871713c47ba88cc0df6c8d224c28ac58d0512b8bf1b672786cc2fa0b1a79cc045c473e1e14b5a9cce4b01e623dd252893294d6aff9d1c2 languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/mdx-loader@npm:0.0.0-5569" +"@docusaurus/mdx-loader@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/mdx-loader@npm:0.0.0-5580" dependencies: "@babel/parser": ^7.21.2 "@babel/traverse": ^7.21.2 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 "@mdx-js/mdx": ^2.1.5 escape-html: ^1.0.3 estree-util-value-to-estree: ^2.1.0 @@ -1744,6 +1744,7 @@ __metadata: image-size: ^1.0.2 mdast-util-mdx: ^2.0.0 mdast-util-to-string: ^3.0.0 + rehype-raw: ^6.1.1 remark-comment: ^1.0.0 remark-directive: ^2.0.1 remark-emoji: ^2.2.0 @@ -1757,16 +1758,16 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: bcf3b58ea3840d648ddc81c090c9905d559f642d8dc495f3fa86b377ae0bdabb6e1486ae2b258efa459a8bcf1da729a4a3a0c144f0de5dc083155b6d5c83099c + checksum: b32812e0bca91a29761fda742a790f67077bb7e8860e20e83f009e297ca49017192fa14051ab82f1a3e66800de9e5a0b561b32ce2dffb4eecc0aee48116d3490 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/module-type-aliases@npm:0.0.0-5569" +"@docusaurus/module-type-aliases@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/module-type-aliases@npm:0.0.0-5580" dependencies: "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 0.0.0-5569 + "@docusaurus/types": 0.0.0-5580 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -1776,19 +1777,19 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 08168317c606e44f8ead775bfc23feaeb3a03178a19a07504130a32cbf189926c08ef40cdc4f00a6df0983383ca0145a42df9112451b15a19067d8b6b10d5f89 + checksum: b5b3544f2f2d395c1d406a1b3f03f719aee3aa3fd7603c54af3b09c4fb8bb153cf2ee6697bc9cfc9fb2550a11a3e474a52c9f2c132924e2be60662ffc6379ace languageName: node linkType: hard -"@docusaurus/plugin-client-redirects@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-client-redirects@npm:0.0.0-5569" +"@docusaurus/plugin-client-redirects@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-client-redirects@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 eta: ^2.0.1 fs-extra: ^11.1.0 lodash: ^4.17.21 @@ -1796,21 +1797,21 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: f082956089fc889ea67b89c5c19ad6cd0bc9bb35b663a701f05905786938b1302b8667c2b6d0354bcf9efd35496a5920e1871b488fbc6285d0e36cfe3187e84e + checksum: 7414d2026446862505d0c679ad3757107f28100ea76309d2a024ebe78865f2fcf3e3b85c3117361142e319362b5a5b22e6bce968763fdfd0741b6a60d2eb3f4b languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-content-blog@npm:0.0.0-5569" +"@docusaurus/plugin-content-blog@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-content-blog@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/mdx-loader": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/mdx-loader": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 cheerio: ^1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.0 @@ -1823,21 +1824,21 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: b9eef1200e1b9bf1cfa7c4d4cb62b7344306d3a096c0cbfc36afd4b973a940b1bf9d6dc62124a0028bbd466313c7ee219444ebe2856588748d2fc33d1f48ae80 + checksum: 0c5d37fa84298ce12b2a0f5c1dea1ee7d72d4b28c545fd081f3c3e5f93f15a980d877dcf88718aa1f4b8a03abf3d0c8c0df10d0a2ef22aac7a8a96d2786f91c2 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-content-docs@npm:0.0.0-5569" +"@docusaurus/plugin-content-docs@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-content-docs@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/mdx-loader": 0.0.0-5569 - "@docusaurus/module-type-aliases": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/mdx-loader": 0.0.0-5580 + "@docusaurus/module-type-aliases": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 "@types/react-router-config": ^5.0.6 combine-promises: ^1.1.0 fs-extra: ^11.1.0 @@ -1850,133 +1851,133 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 544d51dbb6c9037916aa8e3ed493624029ffdac0d0da70cfdb74f1d431a8da071eeeb0d567be6f63d48f9922f1594f08f950478a4ea427fae8001ff0b4ac5d83 + checksum: fa58801bf0cebf055ed11adbadc3f27f7ed0ddb95174ab60bab76a21f759dc7abdfdd15f32141f7e259090c456634ee2556ac9a7daaaf7f5f6e3666d9f247d00 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-content-pages@npm:0.0.0-5569" +"@docusaurus/plugin-content-pages@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-content-pages@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/mdx-loader": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/mdx-loader": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 fs-extra: ^11.1.0 tslib: ^2.5.0 webpack: ^5.76.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 16fa680c069d57d9d299ef515487a773c5b89d605cfe5b843392a7bce5e59b539b1855d7e0f2e11878b3021038bff6468b5f4adb9af7dc06884d7207772c2f95 + checksum: 42bf814d9bf5540b8b2f8045f1577c49d3fca4a85069865695ff5dd9fa3f935283f9d46f920c4dd0a28190cf3b342d432b0985636bae9f05280835f73aec8c87 languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-debug@npm:0.0.0-5569" +"@docusaurus/plugin-debug@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-debug@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 fs-extra: ^11.1.0 react-json-view: ^1.21.3 tslib: ^2.5.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 0e3b8f5a92bc2b2ab193d76be6174b521238da7b4627775a852a4b4ff8690af28ab4586adbb84fc03abc6da276efc7474eed9350577b457e532defeb638d3184 + checksum: dc58659adab3c859daa2e0dfc0b5b588d490a4d2bb313dcfdc9e92d559d0c4145c686b001805ad44a1f2a0f55f87524637a34844a4438cfeec479a2c24ec1c4d languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-google-analytics@npm:0.0.0-5569" +"@docusaurus/plugin-google-analytics@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-google-analytics@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 tslib: ^2.5.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: a3e55d3a616009db499ca61493f9cf308c8ae012ec1ff680bff20c3b0b486f8d5d9552fd5c3d7b198e6c72d8e13ace7808d978bd8d56496953d2fd51d5ce0c32 + checksum: f66a737a2b8b08648f28a279784e527fff34e2dba6f3022ec83b01a7f1781bfa0f208fac1db1fc919c1a01d405755c0816304cf4912e7b434b3924d5a968e6b0 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-google-gtag@npm:0.0.0-5569" +"@docusaurus/plugin-google-gtag@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-google-gtag@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 "@types/gtag.js": ^0.0.12 tslib: ^2.5.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: d0a7f58bea6d5bfd786120ab6c75ab10a4d67bae1d60aadedba649a516f2f9e49237a96a7764f964c79084ae500b9520761cbf6aab60bd5e43bb976f04dd3194 + checksum: 6b05e7c2a8e4d757660acca1131a0e3abfd21c5544a31e93bd08ff9c75deb5f3b131ed0e47283bbc2f102e00947ab7a64ee4d5a53f300e98fc82ec13c4a6eda1 languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-google-tag-manager@npm:0.0.0-5569" +"@docusaurus/plugin-google-tag-manager@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-google-tag-manager@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 tslib: ^2.5.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: acafad7eea5ba06c62addcef4f3cfaa6c43193827ec4b6c2d39ed2799df5301defa8ac8c73d49e35c328bd118c78412745f088764d97eac00da090be8e7906e5 + checksum: 8904b150b2faa05dc49fd957ca8c392605e53073d031dfedb098be2abae924c3faf4f5e26ecfea91fe452695699801de9882a85a4371a1a35ca05fd57de232ae languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/plugin-sitemap@npm:0.0.0-5569" +"@docusaurus/plugin-sitemap@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/plugin-sitemap@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 fs-extra: ^11.1.0 sitemap: ^7.1.1 tslib: ^2.5.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 53fd5944a1cfbbe252e3f4398acf8aea3605ca3c5fb9ec48700ce6c162744bae541ccecd1d71e884777dfc2e98c6fa9a01b0f98829e6018e59003c3d4f4a1612 + checksum: 4243cf4ed649d8e9a29b122ce23f1a6194cc5d7fc244e33326320315d8ff2756b18b9d85a0f0d49df33b2e68224c1b747e87ad5fa9944e7572bc761f641c5b77 languageName: node linkType: hard -"@docusaurus/preset-classic@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/preset-classic@npm:0.0.0-5569" +"@docusaurus/preset-classic@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/preset-classic@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/plugin-content-blog": 0.0.0-5569 - "@docusaurus/plugin-content-docs": 0.0.0-5569 - "@docusaurus/plugin-content-pages": 0.0.0-5569 - "@docusaurus/plugin-debug": 0.0.0-5569 - "@docusaurus/plugin-google-analytics": 0.0.0-5569 - "@docusaurus/plugin-google-gtag": 0.0.0-5569 - "@docusaurus/plugin-google-tag-manager": 0.0.0-5569 - "@docusaurus/plugin-sitemap": 0.0.0-5569 - "@docusaurus/theme-classic": 0.0.0-5569 - "@docusaurus/theme-common": 0.0.0-5569 - "@docusaurus/theme-search-algolia": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/plugin-content-blog": 0.0.0-5580 + "@docusaurus/plugin-content-docs": 0.0.0-5580 + "@docusaurus/plugin-content-pages": 0.0.0-5580 + "@docusaurus/plugin-debug": 0.0.0-5580 + "@docusaurus/plugin-google-analytics": 0.0.0-5580 + "@docusaurus/plugin-google-gtag": 0.0.0-5580 + "@docusaurus/plugin-google-tag-manager": 0.0.0-5580 + "@docusaurus/plugin-sitemap": 0.0.0-5580 + "@docusaurus/theme-classic": 0.0.0-5580 + "@docusaurus/theme-common": 0.0.0-5580 + "@docusaurus/theme-search-algolia": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: a20013db1bd1c77e6fc2b901326d62f3003b6f6e6191f26aae6968cc2402837c0e84cc54571849d2af811fdae74d9359c0e96775d61b9f3efbbe881898e7f9a3 + checksum: 3aa48aea40e33c2c7adcad54918e117b1f1d917eba110889d85a273e82b4bbf0d73d9e5bb8c5aaadd846ec341981bbe701014cbd93ddf55c83245ce1bc4a56a6 languageName: node linkType: hard @@ -1992,22 +1993,22 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/theme-classic@npm:0.0.0-5569" +"@docusaurus/theme-classic@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/theme-classic@npm:0.0.0-5580" dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/mdx-loader": 0.0.0-5569 - "@docusaurus/module-type-aliases": 0.0.0-5569 - "@docusaurus/plugin-content-blog": 0.0.0-5569 - "@docusaurus/plugin-content-docs": 0.0.0-5569 - "@docusaurus/plugin-content-pages": 0.0.0-5569 - "@docusaurus/theme-common": 0.0.0-5569 - "@docusaurus/theme-translations": 0.0.0-5569 - "@docusaurus/types": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/mdx-loader": 0.0.0-5580 + "@docusaurus/module-type-aliases": 0.0.0-5580 + "@docusaurus/plugin-content-blog": 0.0.0-5580 + "@docusaurus/plugin-content-docs": 0.0.0-5580 + "@docusaurus/plugin-content-pages": 0.0.0-5580 + "@docusaurus/theme-common": 0.0.0-5580 + "@docusaurus/theme-translations": 0.0.0-5580 + "@docusaurus/types": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 "@mdx-js/react": ^2.1.5 clsx: ^1.2.1 copy-text-to-clipboard: ^3.0.1 @@ -2024,21 +2025,21 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: ee25082a4abc0d812cc54ee1bea642766f903cfa47d28c6a6efbc53cdaacf67bee594a4745c7ae97fe3ba6ddb136de36dd0c8cda2c310c5b40c9023bee70fcbb + checksum: 6a8f99d5143017d4754601fbf6487b697dc77945f730763917578abe0a1ef694607f888d824146aef86fdc2a620f0ddbd4925a23dcfc15b57d8338c1de73d526 languageName: node linkType: hard -"@docusaurus/theme-common@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/theme-common@npm:0.0.0-5569" +"@docusaurus/theme-common@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/theme-common@npm:0.0.0-5580" dependencies: - "@docusaurus/mdx-loader": 0.0.0-5569 - "@docusaurus/module-type-aliases": 0.0.0-5569 - "@docusaurus/plugin-content-blog": 0.0.0-5569 - "@docusaurus/plugin-content-docs": 0.0.0-5569 - "@docusaurus/plugin-content-pages": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-common": 0.0.0-5569 + "@docusaurus/mdx-loader": 0.0.0-5580 + "@docusaurus/module-type-aliases": 0.0.0-5580 + "@docusaurus/plugin-content-blog": 0.0.0-5580 + "@docusaurus/plugin-content-docs": 0.0.0-5580 + "@docusaurus/plugin-content-pages": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-common": 0.0.0-5580 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2051,22 +2052,22 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 26a2d7dd6fd8b97e67db3bc093fcb9ce6f14d561aeccf94c3334d18a9a2900483dcb0ec4bb28d31e910bea459f20e4445207d5156c9cc02bd72601eb0256e3cc + checksum: 99524cb36a520568f63140734daaea8d56b35c0c8de3c36cb0102a93a0714f31a68aa5302607b9113a68e1b9fb7d73fd53ac80aa82ce48bf6f2d9e304ce21da2 languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/theme-search-algolia@npm:0.0.0-5569" +"@docusaurus/theme-search-algolia@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/theme-search-algolia@npm:0.0.0-5580" dependencies: "@docsearch/react": ^3.3.3 - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/plugin-content-docs": 0.0.0-5569 - "@docusaurus/theme-common": 0.0.0-5569 - "@docusaurus/theme-translations": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 - "@docusaurus/utils-validation": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/plugin-content-docs": 0.0.0-5580 + "@docusaurus/theme-common": 0.0.0-5580 + "@docusaurus/theme-translations": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 + "@docusaurus/utils-validation": 0.0.0-5580 algoliasearch: ^4.15.0 algoliasearch-helper: ^3.12.0 clsx: ^1.2.1 @@ -2078,23 +2079,23 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 16178b7b9278c91eaedbb1629192dc2255939de6f509b721305c4c1795283e0fd4f859b305ce051ec5efdbe71884ceede6239445916b60ebec1858e3b5161d8f + checksum: efc6054ad979b9fde43bec8befeb41c0f9ca609832b51e4da42fdcdfd7e4ee599fd3e6949c576d9ff348c0ffd044a4dbb07638a1990f57586f493ba394369c96 languageName: node linkType: hard -"@docusaurus/theme-translations@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/theme-translations@npm:0.0.0-5569" +"@docusaurus/theme-translations@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/theme-translations@npm:0.0.0-5580" dependencies: fs-extra: ^11.1.0 tslib: ^2.5.0 - checksum: 695f94ddc66d54b649042f0fb0a88b692613d10898ee3306c6c9b52340373493ac9bcceec9263332454d7c9179339517e40b083e949510f9e48ec834bc61fbb3 + checksum: 1555956d2a7cf3122ded374937559ab19e6a6620fd0910d6bdbf48be78a10e595cfd9a0b9157c129f36f0bfae4297f07991f071a394c87cb9d2facee04597dd2 languageName: node linkType: hard -"@docusaurus/types@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/types@npm:0.0.0-5569" +"@docusaurus/types@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/types@npm:0.0.0-5580" dependencies: "@types/history": ^4.7.11 "@types/react": "*" @@ -2107,13 +2108,13 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 956b7af3a75b3632d1ff330d018353b38b22b3f4af8b39f452fcde33d74c70312dadd3e3bb40e04ecbe02e2462a67bfcbd4ef631462a9c710616c83186930b69 + checksum: 5df67f562c5d516eb020ecf63e6343e1d6d18e2716b1b530a24c5d63b48229623222861c1a69f0e4715c34a768f7c05599340f1af18ca1259709467fb1149af9 languageName: node linkType: hard -"@docusaurus/utils-common@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/utils-common@npm:0.0.0-5569" +"@docusaurus/utils-common@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/utils-common@npm:0.0.0-5580" dependencies: tslib: ^2.5.0 peerDependencies: @@ -2121,28 +2122,28 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 7d98e31beea34be91de7fdc971033439e412f535617707c79c4d2c0653c769ff4ce7521bd87f038811ccbae3b1d5c0e5d26eab9935ee8bc3515b926cbe175365 + checksum: 238b2f12607834164fa82f9a3154703b75609719888cf96f06c9f70c17ab76a46babcfd66dce4f2722ecaaf47742a40a606101f0578f2345845fa23b6f262b5d languageName: node linkType: hard -"@docusaurus/utils-validation@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/utils-validation@npm:0.0.0-5569" +"@docusaurus/utils-validation@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/utils-validation@npm:0.0.0-5580" dependencies: - "@docusaurus/logger": 0.0.0-5569 - "@docusaurus/utils": 0.0.0-5569 + "@docusaurus/logger": 0.0.0-5580 + "@docusaurus/utils": 0.0.0-5580 joi: ^17.8.3 js-yaml: ^4.1.0 tslib: ^2.5.0 - checksum: b16730923e0d6fa627ca3e3105c152e814d540badb93f0a2ae1194672a76f8269ed48ed5c8f3259c0e0b9dfc6dc939035e0ac2e675b283ac4d414c642a95c893 + checksum: cf0602b2411738adc47f5596fd4a3076137aa754aca24a4630700dc6355fed07e9a66ec093e438fa1199d9076bebae036317d073a604e4f0666f8390ceb73b5d languageName: node linkType: hard -"@docusaurus/utils@npm:0.0.0-5569": - version: 0.0.0-5569 - resolution: "@docusaurus/utils@npm:0.0.0-5569" +"@docusaurus/utils@npm:0.0.0-5580": + version: 0.0.0-5580 + resolution: "@docusaurus/utils@npm:0.0.0-5580" dependencies: - "@docusaurus/logger": 0.0.0-5569 + "@docusaurus/logger": 0.0.0-5580 "@svgr/webpack": ^6.5.1 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 @@ -2163,7 +2164,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 33e044f9b5328cf9d1b17637fa41a6138c5e18b5f3d73389bbb9f71735a273a9e27660d9a9103766406549edfa0691e2524cc84e6ebc2b0d308991df3bee0dd9 + checksum: c9b085d3724cba748b3db763f056742aace45cc58a636e23513ee6a7db781558377de5507b651b3566562fa71eebb42ac835034cdcbcc2c77edf9b4009c6a215 languageName: node linkType: hard @@ -2991,6 +2992,13 @@ __metadata: languageName: node linkType: hard +"@types/parse5@npm:^6.0.0": + version: 6.0.3 + resolution: "@types/parse5@npm:6.0.3" + checksum: ddb59ee4144af5dfcc508a8dcf32f37879d11e12559561e65788756b95b33e6f03ea027d88e1f5408f9b7bfb656bf630ace31a2169edf44151daaf8dd58df1b7 + languageName: node + linkType: hard + "@types/prop-types@npm:*": version: 15.7.5 resolution: "@types/prop-types@npm:15.7.5" @@ -3737,10 +3745,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-microsite@workspace:." dependencies: - "@docusaurus/core": 0.0.0-5569 - "@docusaurus/module-type-aliases": 0.0.0-5569 - "@docusaurus/plugin-client-redirects": 0.0.0-5569 - "@docusaurus/preset-classic": 0.0.0-5569 + "@docusaurus/core": 0.0.0-5580 + "@docusaurus/module-type-aliases": 0.0.0-5580 + "@docusaurus/plugin-client-redirects": 0.0.0-5580 + "@docusaurus/preset-classic": 0.0.0-5580 "@spotify/prettier-config": ^14.0.0 "@swc/core": ^1.3.46 "@tsconfig/docusaurus": ^1.0.6 @@ -6132,6 +6140,21 @@ __metadata: languageName: node linkType: hard +"hast-util-from-parse5@npm:^7.0.0": + version: 7.1.2 + resolution: "hast-util-from-parse5@npm:7.1.2" + dependencies: + "@types/hast": ^2.0.0 + "@types/unist": ^2.0.0 + hastscript: ^7.0.0 + property-information: ^6.0.0 + vfile: ^5.0.0 + vfile-location: ^4.0.0 + web-namespaces: ^2.0.0 + checksum: 7b4ed5b508b1352127c6719f7b0c0880190cf9859fe54ccaf7c9228ecf623d36cef3097910b3874d2fe1aac6bf4cf45d3cc2303daac3135a05e9ade6534ddddb + languageName: node + linkType: hard + "hast-util-parse-selector@npm:^3.0.0": version: 3.1.1 resolution: "hast-util-parse-selector@npm:3.1.1" @@ -6141,6 +6164,25 @@ __metadata: languageName: node linkType: hard +"hast-util-raw@npm:^7.2.0": + version: 7.2.3 + resolution: "hast-util-raw@npm:7.2.3" + dependencies: + "@types/hast": ^2.0.0 + "@types/parse5": ^6.0.0 + hast-util-from-parse5: ^7.0.0 + hast-util-to-parse5: ^7.0.0 + html-void-elements: ^2.0.0 + parse5: ^6.0.0 + unist-util-position: ^4.0.0 + unist-util-visit: ^4.0.0 + vfile: ^5.0.0 + web-namespaces: ^2.0.0 + zwitch: ^2.0.0 + checksum: 21857eea3ffb8fd92d2d9be7793b56d0b2c40db03c4cfa14828855ae41d7c584917aa83efb7157220b2e41e25e95f81f24679ac342c35145e5f1c1d39015f81f + languageName: node + linkType: hard + "hast-util-to-estree@npm:^2.0.0": version: 2.3.2 resolution: "hast-util-to-estree@npm:2.3.2" @@ -6164,6 +6206,20 @@ __metadata: languageName: node linkType: hard +"hast-util-to-parse5@npm:^7.0.0": + version: 7.1.0 + resolution: "hast-util-to-parse5@npm:7.1.0" + dependencies: + "@types/hast": ^2.0.0 + comma-separated-tokens: ^2.0.0 + property-information: ^6.0.0 + space-separated-tokens: ^2.0.0 + web-namespaces: ^2.0.0 + zwitch: ^2.0.0 + checksum: 3a7f2175a3db599bbae7e49ba73d3e5e688e5efca7590ff50130ba108ad649f728402815d47db49146f6b94c14c934bf119915da9f6964e38802c122bcc8af6b + languageName: node + linkType: hard + "hast-util-whitespace@npm:^2.0.0": version: 2.0.1 resolution: "hast-util-whitespace@npm:2.0.1" @@ -6171,7 +6227,7 @@ __metadata: languageName: node linkType: hard -"hastscript@npm:^7.1.0": +"hastscript@npm:^7.0.0, hastscript@npm:^7.1.0": version: 7.2.0 resolution: "hastscript@npm:7.2.0" dependencies: @@ -6276,6 +6332,13 @@ __metadata: languageName: node linkType: hard +"html-void-elements@npm:^2.0.0": + version: 2.0.1 + resolution: "html-void-elements@npm:2.0.1" + checksum: 06d41f13b9d5d6e0f39861c4bec9a9196fa4906d56cd5cf6cf54ad2e52a85bf960cca2bf9600026bde16c8331db171bedba5e5a35e2e43630c8f1d497b2fb658 + languageName: node + linkType: hard + "html-webpack-plugin@npm:^5.5.0": version: 5.5.0 resolution: "html-webpack-plugin@npm:5.5.0" @@ -8735,6 +8798,13 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^6.0.0": + version: 6.0.1 + resolution: "parse5@npm:6.0.1" + checksum: 7d569a176c5460897f7c8f3377eff640d54132b9be51ae8a8fa4979af940830b2b0c296ce75e5bd8f4041520aadde13170dbdec44889975f906098ea0002f4bd + languageName: node + linkType: hard + "parse5@npm:^7.0.0": version: 7.1.2 resolution: "parse5@npm:7.1.2" @@ -9901,6 +9971,17 @@ __metadata: languageName: node linkType: hard +"rehype-raw@npm:^6.1.1": + version: 6.1.1 + resolution: "rehype-raw@npm:6.1.1" + dependencies: + "@types/hast": ^2.0.0 + hast-util-raw: ^7.2.0 + unified: ^10.0.0 + checksum: a1f9d309e609f49fb1f1e06e722705f4dd2e569653a89f756eaccb33b612cf1bb511216a81d10a619d11d047afc161e4b3cb99b957df05a8ba8fdbd5843f949a + languageName: node + linkType: hard + "relateurl@npm:^0.2.7": version: 0.2.7 resolution: "relateurl@npm:0.2.7" @@ -11526,6 +11607,13 @@ __metadata: languageName: node linkType: hard +"web-namespaces@npm:^2.0.0": + version: 2.0.1 + resolution: "web-namespaces@npm:2.0.1" + checksum: b6d9f02f1a43d0ef0848a812d89c83801d5bbad57d8bb61f02eb6d7eb794c3736f6cc2e1191664bb26136594c8218ac609f4069722c6f56d9fc2d808fa9271c6 + languageName: node + linkType: hard + "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" diff --git a/package.json b/package.json index 44778ae926..3a7e05d65a 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.14.0-next.1", + "version": "1.14.0", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3" diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 5d781b58ca..7cb6737b73 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/app-defaults +## 1.3.1 + +### Patch Changes + +- 575d9178eff: Added a System Icon for resource entities. + This can be obtained using: + + ```ts + useApp().getSystemIcon('kind:resource'); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + +## 1.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + ## 1.3.1-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 0a8f2e5dc1..90f50d0eff 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.3.1-next.1", + "version": "1.3.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index b20fafb995..5fdee05829 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,145 @@ # example-app +## 0.2.83 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-tech-insights@0.3.10 + - @backstage/plugin-scaffolder@1.13.1 + - @backstage/plugin-devtools@0.1.0 + - @backstage/plugin-kubernetes@0.9.0 + - @backstage/plugin-search@1.3.0 + - @backstage/plugin-home@0.5.2 + - @backstage/plugin-explore@0.4.3 + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/app-defaults@1.3.1 + - @backstage/plugin-badges@0.2.42 + - @backstage/plugin-tech-radar@0.6.4 + - @backstage/cli@0.22.7 + - @backstage/plugin-stack-overflow@0.1.15 + - @backstage/plugin-gcalendar@0.3.14 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-app-api@1.8.0 + - @backstage/plugin-scaffolder-react@1.4.0 + - @backstage/plugin-catalog-graph@0.2.30 + - @backstage/plugin-circleci@0.3.18 + - @backstage/plugin-search-react@1.6.0 + - @backstage/plugin-org@0.6.8 + - @backstage/core-components@0.13.1 + - @backstage/plugin-azure-devops@0.3.0 + - @backstage/plugin-jenkins@0.8.0 + - @backstage/plugin-octopus-deploy@0.2.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.13 + - @backstage/plugin-user-settings@0.7.3 + - @backstage/plugin-shortcuts@0.3.10 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-airbrake@0.3.18 + - @backstage/plugin-api-docs@0.9.3 + - @backstage/plugin-azure-sites@0.1.7 + - @backstage/plugin-cloudbuild@0.3.18 + - @backstage/plugin-code-coverage@0.2.11 + - @backstage/plugin-cost-insights@0.12.7 + - @backstage/plugin-dynatrace@5.0.0 + - @backstage/plugin-entity-feedback@0.2.1 + - @backstage/plugin-gcp-projects@0.3.37 + - @backstage/plugin-github-actions@0.5.18 + - @backstage/plugin-gocd@0.1.24 + - @backstage/plugin-graphiql@0.2.50 + - @backstage/plugin-kafka@0.3.18 + - @backstage/plugin-lighthouse@0.4.3 + - @backstage/plugin-linguist@0.1.3 + - @backstage/plugin-microsoft-calendar@0.1.3 + - @backstage/plugin-newrelic@0.3.36 + - @backstage/plugin-pagerduty@0.5.11 + - @backstage/plugin-playlist@0.1.9 + - @backstage/plugin-puppetdb@0.1.1 + - @backstage/plugin-rollbar@0.4.18 + - @backstage/plugin-sentry@0.5.3 + - @backstage/plugin-stackstorm@0.1.2 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/plugin-todo@0.2.20 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-apache-airflow@0.2.11 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-catalog-import@0.9.8 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-newrelic-dashboard@0.2.11 + - @backstage/plugin-permission-react@0.4.12 + - @backstage/plugin-search-common@1.2.3 + - @internal/plugin-catalog-customized@0.0.10 + +## 0.2.83-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools@0.1.0-next.0 + - @backstage/plugin-kubernetes@0.9.0-next.2 + - @backstage/plugin-home@0.5.2-next.2 + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-badges@0.2.42-next.2 + - @backstage/plugin-tech-radar@0.6.4-next.2 + - @backstage/plugin-scaffolder-react@1.4.0-next.2 + - @backstage/plugin-explore@0.4.3-next.2 + - @backstage/plugin-org@0.6.8-next.2 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-azure-devops@0.3.0-next.2 + - @backstage/plugin-stack-overflow@0.1.15-next.2 + - @backstage/app-defaults@1.3.1-next.2 + - @backstage/cli@0.22.7-next.0 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-airbrake@0.3.18-next.2 + - @backstage/plugin-api-docs@0.9.3-next.2 + - @backstage/plugin-azure-sites@0.1.7-next.2 + - @backstage/plugin-catalog-graph@0.2.30-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-circleci@0.3.18-next.2 + - @backstage/plugin-cloudbuild@0.3.18-next.2 + - @backstage/plugin-code-coverage@0.2.11-next.2 + - @backstage/plugin-cost-insights@0.12.7-next.2 + - @backstage/plugin-dynatrace@5.0.0-next.2 + - @backstage/plugin-entity-feedback@0.2.1-next.2 + - @backstage/plugin-gcalendar@0.3.14-next.1 + - @backstage/plugin-gcp-projects@0.3.37-next.1 + - @backstage/plugin-github-actions@0.5.18-next.2 + - @backstage/plugin-gocd@0.1.24-next.2 + - @backstage/plugin-graphiql@0.2.50-next.1 + - @backstage/plugin-jenkins@0.7.17-next.2 + - @backstage/plugin-kafka@0.3.18-next.2 + - @backstage/plugin-lighthouse@0.4.3-next.2 + - @backstage/plugin-linguist@0.1.3-next.2 + - @backstage/plugin-microsoft-calendar@0.1.3-next.1 + - @backstage/plugin-newrelic@0.3.36-next.1 + - @backstage/plugin-octopus-deploy@0.2.0-next.2 + - @backstage/plugin-pagerduty@0.5.11-next.2 + - @backstage/plugin-playlist@0.1.9-next.2 + - @backstage/plugin-puppetdb@0.1.1-next.2 + - @backstage/plugin-rollbar@0.4.18-next.2 + - @backstage/plugin-scaffolder@1.13.1-next.2 + - @backstage/plugin-search@1.3.0-next.2 + - @backstage/plugin-sentry@0.5.3-next.2 + - @backstage/plugin-shortcuts@0.3.10-next.2 + - @backstage/plugin-stackstorm@0.1.2-next.1 + - @backstage/plugin-tech-insights@0.3.10-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.13-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/plugin-todo@0.2.20-next.2 + - @backstage/plugin-user-settings@0.7.3-next.2 + - @backstage/plugin-apache-airflow@0.2.11-next.1 + - @backstage/plugin-catalog-import@0.9.8-next.2 + - @backstage/plugin-newrelic-dashboard@0.2.11-next.2 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + - @internal/plugin-catalog-customized@0.0.10-next.2 + ## 0.2.83-next.1 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index d4941ecd48..c2330244d0 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.83-next.1", + "version": "0.2.83", "private": true, "backstage": { "role": "frontend" @@ -29,6 +29,7 @@ "@backstage/plugin-cloudbuild": "workspace:^", "@backstage/plugin-code-coverage": "workspace:^", "@backstage/plugin-cost-insights": "workspace:^", + "@backstage/plugin-devtools": "workspace:^", "@backstage/plugin-dynatrace": "workspace:^", "@backstage/plugin-entity-feedback": "workspace:^", "@backstage/plugin-explore": "workspace:^", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 19edd9640d..bc9eac8c64 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -109,6 +109,8 @@ import { TwoColumnLayout } from './components/scaffolder/customScaffolderLayouts import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card'; import { StackstormPage } from '@backstage/plugin-stackstorm'; import { PuppetDbPage } from '@backstage/plugin-puppetdb'; +import { DevToolsPage } from '@backstage/plugin-devtools'; +import { customDevToolsPage } from './components/devtools/CustomDevToolsPage'; const app = createApp({ apis, @@ -291,6 +293,9 @@ const routes = ( } /> } /> } /> + }> + {customDevToolsPage} + ); diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index 904fa4a7d4..ffaf72296a 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -52,6 +52,7 @@ import { MyGroupsSidebarItem } from '@backstage/plugin-org'; import { SearchModal } from '../search/SearchModal'; import Score from '@material-ui/icons/Score'; import { useApp } from '@backstage/core-plugin-api'; +import BuildIcon from '@material-ui/icons/Build'; const useSidebarLogoStyles = makeStyles({ root: { @@ -176,6 +177,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( to="/settings" > + {children} diff --git a/packages/app/src/components/devtools/CustomDevToolsPage.tsx b/packages/app/src/components/devtools/CustomDevToolsPage.tsx new file mode 100644 index 0000000000..dfe70426aa --- /dev/null +++ b/packages/app/src/components/devtools/CustomDevToolsPage.tsx @@ -0,0 +1,44 @@ +/* + * Copyright 2022 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 { + ConfigContent, + ExternalDependenciesContent, + InfoContent, +} from '@backstage/plugin-devtools'; +import { DevToolsLayout } from '@backstage/plugin-devtools'; +import React from 'react'; + +const DevToolsPage = () => { + return ( + + + + + + + + + + + + ); +}; + +export const customDevToolsPage = ; diff --git a/packages/app/src/components/home/HomePage.tsx b/packages/app/src/components/home/HomePage.tsx index 26a7ab60f3..da1d0d425c 100644 --- a/packages/app/src/components/home/HomePage.tsx +++ b/packages/app/src/components/home/HomePage.tsx @@ -21,12 +21,15 @@ import { ClockConfig, HomePageStarredEntities, CustomHomepageGrid, + HomePageToolkit, + HomePageCompanyLogo, } from '@backstage/plugin-home'; import { Content, Header, Page } from '@backstage/core-components'; import { HomePageSearchBar } from '@backstage/plugin-search'; import { HomePageCalendar } from '@backstage/plugin-gcalendar'; import { MicrosoftCalendarCard } from '@backstage/plugin-microsoft-calendar'; import React from 'react'; +import HomeIcon from '@material-ui/icons/Home'; const clockConfigs: ClockConfig[] = [ { @@ -55,12 +58,26 @@ const timeFormat: Intl.DateTimeFormatOptions = { const defaultConfig = [ { - component: 'HomePageSearchBar', + component: 'CompanyLogo', x: 0, y: 0, width: 12, height: 1, }, + { + component: 'WelcomeTitle', + x: 0, + y: 1, + width: 12, + height: 1, + }, + { + component: 'HomePageSearchBar', + x: 0, + y: 2, + width: 12, + height: 1, + }, ]; export const homePage = ( @@ -78,6 +95,17 @@ export const homePage = ( + + + , + }, + ]} + /> diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 00e7582ad3..dcb0e722c0 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/backend-app-api +## 0.4.3 + +### Patch Changes + +- cf13b482f9e: Switch `configServiceFactory` to use `ConfigSources` from `@backstage/config-loader` to load config. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 0.4.3-next.1 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index a21484ff2e..dc5b38daae 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.4.3-next.1", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index fc6d99cf93..cdf7f6259d 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/backend-common +## 0.18.5 + +### Patch Changes + +- 0297f7a54af: Remove the direct dependency on deprecated "request" library +- 284db225083: Updated the `DatabaseManager` to include the plugin id in the Postgres application name of the database connections created for each plugin. +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- 42d817e76ab: Added `HostDiscovery` to supersede deprecated `SingleHostDiscovery` (deprecated due to name) +- Updated dependencies + - @backstage/config-loader@1.3.0 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/backend-app-api@0.4.3 + - @backstage/backend-dev-utils@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 0.18.5-next.1 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 045a385218..914400368a 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.18.5-next.1", + "version": "0.18.5", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -46,10 +46,10 @@ "test:kubernetes": "backstage-cli package test -t KubernetesContainerRunner --no-watch" }, "dependencies": { - "@aws-sdk/abort-controller": "^3.208.0", - "@aws-sdk/client-s3": "^3.208.0", - "@aws-sdk/credential-providers": "^3.208.0", - "@aws-sdk/types": "^3.208.0", + "@aws-sdk/abort-controller": "^3.310.0", + "@aws-sdk/client-s3": "^3.310.0", + "@aws-sdk/credential-providers": "^3.310.0", + "@aws-sdk/types": "^3.310.0", "@backstage/backend-app-api": "workspace:^", "@backstage/backend-dev-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", @@ -114,7 +114,7 @@ } }, "devDependencies": { - "@aws-sdk/util-stream-node": "^3.208.0", + "@aws-sdk/util-stream-node": "^3.310.0", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/archiver": "^5.1.0", diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 52043b4ecf..49d5a8bf1f 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-defaults +## 0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-app-api@0.4.3 + - @backstage/backend-plugin-api@0.5.2 + ## 0.1.10-next.1 ### Patch Changes diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index d99e462efa..09b5b82dfc 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.1.10-next.1", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index 2eea18b4af..8253a108b9 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,37 @@ # example-backend-next +## 0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/plugin-kubernetes-backend@0.11.0 + - @backstage/plugin-todo-backend@0.1.42 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-search-backend@1.3.1 + - @backstage/backend-defaults@0.1.10 + - @backstage/plugin-app-backend@0.3.45 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-search-backend-module-catalog@0.1.1 + - @backstage/plugin-search-backend-module-explore@0.1.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.1 + - @backstage/plugin-techdocs-backend@1.6.2 + - @backstage/plugin-permission-backend@0.5.20 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/plugin-permission-common@0.7.5 + +## 0.0.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-kubernetes-backend@0.11.0-next.2 + - @backstage/plugin-search-backend@1.3.1-next.2 + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + ## 0.0.11-next.1 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index bf913492ac..a50df741ec 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.11-next.1", + "version": "0.0.11", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 015a54cf45..0255bbbf73 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/backend-openapi-utils +## 0.0.2 + +### Patch Changes + +- fe16bd39e83: Use permalinks for links including a line number reference +- 27956d78671: Adjusted README accordingly after the generated output now has a `.generated.ts` extension +- 021cfbb5152: Corrected resolution of parameter nested schema to use central schemas. +- 799c33047ed: Updated README to reflect changes in `@backstage/repo-tools`. + +## 0.0.2-next.1 + +### Patch Changes + +- fe16bd39e83: Use permalinks for links including a line number reference +- 021cfbb5152: Corrected resolution of parameter nested schema to use central schemas. + ## 0.0.2-next.0 ### Patch Changes diff --git a/packages/backend-openapi-utils/README.md b/packages/backend-openapi-utils/README.md index 122dca0201..ba286f94e8 100644 --- a/packages/backend-openapi-utils/README.md +++ b/packages/backend-openapi-utils/README.md @@ -8,7 +8,7 @@ This package is meant to provide a typed Express router for an OpenAPI spec. Bas ### Configuration -1. Run `yarn --cwd backstage-cli package schema:openapi:generate` to translate your `src/schema/openapi.yaml` to a new Typescript file in `src/schema/openapi.generated.ts`. The command will try to execute both a lint and prettier step on the generated file, where applicable. +1. Run `yarn --cwd backstage-cli package schema openapi generate` to translate your `src/schema/openapi.yaml` to a new Typescript file in `src/schema/openapi.generated.ts`. The command will try to execute both a lint and prettier step on the generated file, where applicable. 2. In your plugin's `src/service/createRouter.ts`, diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index e59da29840..89a4621a49 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-openapi-utils", "description": "OpenAPI typescript support.", - "version": "0.0.2-next.0", + "version": "0.0.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 9a28b1dd3a..cf22e7a9c3 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-plugin-api +## 0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + ## 0.5.2-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 58e103e647..d4c2bef5a2 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.5.2-next.1", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 1ef0203eb1..c7927d1e66 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-tasks +## 0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 0.5.2-next.1 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index b0f5c3afb3..6a87b91202 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.5.2-next.1", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 3ce5006003..7a2ea9c2e6 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/backend-test-utils +## 0.1.37 + +### Patch Changes + +- 63af7f6d53f: Allow specifying custom Docker registry for database tests +- b1eb268bf9d: Added `POSTGRES_11` and `POSTGRES_12` as supported test database IDs. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-app-api@0.4.3 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + ## 0.1.37-next.1 ### Patch Changes diff --git a/packages/backend-test-utils/README.md b/packages/backend-test-utils/README.md index d0f52388bb..f22cb1bd3c 100644 --- a/packages/backend-test-utils/README.md +++ b/packages/backend-test-utils/README.md @@ -12,6 +12,26 @@ cd plugins/my-plugin-backend yarn add --dev @backstage/backend-test-utils ``` +## Environment variables + +- `BACKSTAGE_TEST_DISABLE_DOCKER` + - Setting the value to `1` disables Docker for tests +- `CI` + - Setting the value to `1` enables long-running tests, including the ones utilizing Docker +- `BACKSTAGE_TEST_DOCKER_REGISTRY` + - Docker registry mirror address where to pull images for tests, for example `mycompany.docker.io/mirror` + - See [documentation](https://node.testcontainers.org/configuration/) for information + about authentication (`DOCKER_AUTH_CONFIG`) + +Connection strings for different databases that are used for testing. The value of the +string should point to the running instance of the database. + +- `BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING` +- `BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING` +- `BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING` +- `BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING` +- `BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING` + ## Documentation - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index b23d3b411e..5351ade035 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.37-next.1", + "version": "0.1.37", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts index 89ec21e7cc..8c1d6f5193 100644 --- a/packages/backend-test-utils/src/database/types.ts +++ b/packages/backend-test-utils/src/database/types.ts @@ -16,6 +16,7 @@ import { DatabaseManager } from '@backstage/backend-common'; import { Knex } from 'knex'; +import { getDockerImageForName } from '../util/getDockerImageForName'; /** * The possible databases to test against. @@ -48,35 +49,35 @@ export const allDatabases: Record = POSTGRES_13: { name: 'Postgres 13.x', driver: 'pg', - dockerImageName: 'postgres:13', + dockerImageName: getDockerImageForName('postgres:13'), connectionStringEnvironmentVariableName: 'BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING', }, POSTGRES_12: { name: 'Postgres 12.x', driver: 'pg', - dockerImageName: 'postgres:12', + dockerImageName: getDockerImageForName('postgres:12'), connectionStringEnvironmentVariableName: 'BACKSTAGE_TEST_DATABASE_POSTGRES12_CONNECTION_STRING', }, POSTGRES_11: { name: 'Postgres 11.x', driver: 'pg', - dockerImageName: 'postgres:11', + dockerImageName: getDockerImageForName('postgres:11'), connectionStringEnvironmentVariableName: 'BACKSTAGE_TEST_DATABASE_POSTGRES11_CONNECTION_STRING', }, POSTGRES_9: { name: 'Postgres 9.x', driver: 'pg', - dockerImageName: 'postgres:9', + dockerImageName: getDockerImageForName('postgres:9'), connectionStringEnvironmentVariableName: 'BACKSTAGE_TEST_DATABASE_POSTGRES9_CONNECTION_STRING', }, MYSQL_8: { name: 'MySQL 8.x', driver: 'mysql2', - dockerImageName: 'mysql:8', + dockerImageName: getDockerImageForName('mysql:8'), connectionStringEnvironmentVariableName: 'BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING', }, diff --git a/packages/backend-test-utils/src/util/getDockerImageForName.ts b/packages/backend-test-utils/src/util/getDockerImageForName.ts new file mode 100644 index 0000000000..7869e7b418 --- /dev/null +++ b/packages/backend-test-utils/src/util/getDockerImageForName.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export const getDockerImageForName = (name: string) => { + return process.env.BACKSTAGE_TEST_DOCKER_REGISTRY + ? `${process.env.BACKSTAGE_TEST_DOCKER_REGISTRY}/${name}` + : name; +}; diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index e676df6839..c775d70b2f 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,74 @@ # example-backend +## 0.2.83 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/plugin-devtools-backend@0.1.0 + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/plugin-kubernetes-backend@0.11.0 + - @backstage/plugin-auth-backend@0.18.3 + - @backstage/plugin-badges-backend@0.2.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-todo-backend@0.1.42 + - @backstage/plugin-jenkins-backend@0.2.0 + - @backstage/plugin-azure-sites-backend@0.1.7 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-search-backend@1.3.1 + - example-app@0.2.83 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-app-backend@0.3.45 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/plugin-entity-feedback-backend@0.1.3 + - @backstage/plugin-events-backend@0.2.6 + - @backstage/plugin-playlist-backend@0.3.1 + - @backstage/plugin-rollbar-backend@0.1.42 + - @backstage/plugin-search-backend-module-pg@0.5.6 + - @backstage/plugin-tech-insights-backend@0.5.11 + - @backstage/plugin-techdocs-backend@1.6.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.14 + - @backstage/plugin-adr-backend@0.3.3 + - @backstage/plugin-azure-devops-backend@0.3.24 + - @backstage/plugin-code-coverage-backend@0.2.11 + - @backstage/plugin-explore-backend@0.0.7 + - @backstage/plugin-graphql-backend@0.1.35 + - @backstage/plugin-kafka-backend@0.2.38 + - @backstage/plugin-lighthouse-backend@0.2.1 + - @backstage/plugin-linguist-backend@0.2.2 + - @backstage/plugin-permission-backend@0.5.20 + - @backstage/plugin-proxy-backend@0.2.39 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.29 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## 0.2.83-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-backend@0.1.0-next.0 + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-badges-backend@0.2.0-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.0-next.2 + - @backstage/plugin-kubernetes-backend@0.11.0-next.2 + - @backstage/plugin-auth-backend@0.18.3-next.2 + - @backstage/plugin-search-backend@1.3.1-next.2 + - example-app@0.2.83-next.2 + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.14-next.2 + - @backstage/config@1.0.7 + ## 0.2.83-next.1 ### Patch Changes diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index eca6ce82c2..da25f9736c 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -13,11 +13,14 @@ FROM node:16-bullseye-slim # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, # in which case you should also move better-sqlite3 to "devDependencies" in package.json. +# Additionally, we install dependencies for `techdocs.generator.runIn: local`. +# https://backstage.io/docs/features/techdocs/getting-started#disabling-docker-in-docker-situation-optional RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && \ - apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ - yarn config set python /usr/bin/python3 + apt-get install -y --no-install-recommends libsqlite3-dev python3 python3-pip build-essential && \ + yarn config set python /usr/bin/python3 && \ + pip3 install mkdocs-techdocs-core==1.1.7 # From here on we use the least-privileged `node` user to run the backend. WORKDIR /app diff --git a/packages/backend/package.json b/packages/backend/package.json index 900ee150fc..7d6c1011e4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.83-next.1", + "version": "0.2.83", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -42,6 +42,7 @@ "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-code-coverage-backend": "workspace:^", + "@backstage/plugin-devtools-backend": "workspace:^", "@backstage/plugin-entity-feedback-backend": "workspace:^", "@backstage/plugin-events-backend": "workspace:^", "@backstage/plugin-events-node": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 593d30bc3b..976ad9a577 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -64,6 +64,7 @@ import playlist from './plugins/playlist'; import adr from './plugins/adr'; import lighthouse from './plugins/lighthouse'; import linguist from './plugins/linguist'; +import devTools from './plugins/devtools'; import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; @@ -158,8 +159,8 @@ async function main() { const eventsEnv = useHotMemoize(module, () => createEnv('events')); const exploreEnv = useHotMemoize(module, () => createEnv('explore')); const lighthouseEnv = useHotMemoize(module, () => createEnv('lighthouse')); - const linguistEnv = useHotMemoize(module, () => createEnv('linguist')); + const devToolsEnv = useHotMemoize(module, () => createEnv('devtools')); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); @@ -185,6 +186,7 @@ async function main() { apiRouter.use('/entity-feedback', await entityFeedback(entityFeedbackEnv)); apiRouter.use('/adr', await adr(adrEnv)); apiRouter.use('/linguist', await linguist(linguistEnv)); + apiRouter.use('/devtools', await devTools(devToolsEnv)); apiRouter.use(notFoundHandler()); await lighthouse(lighthouseEnv); diff --git a/packages/backend/src/plugins/devtools.ts b/packages/backend/src/plugins/devtools.ts new file mode 100644 index 0000000000..8e1767ddb1 --- /dev/null +++ b/packages/backend/src/plugins/devtools.ts @@ -0,0 +1,29 @@ +/* + * Copyright 2022 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 { createRouter } from '@backstage/plugin-devtools-backend'; +import { Router } from 'express'; +import type { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return createRouter({ + logger: env.logger, + config: env.config, + permissions: env.permissions, + }); +} diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a8c7207650..b91dad32b7 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/cli +## 0.22.7 + +### Patch Changes + +- 473db605a4f: Enable strict config checking during `backstage-cli config:check` with the new `--strict` option which will surface schema errors. +- d548886872d: Deprecated the use of React 16 +- Updated dependencies + - @backstage/config-loader@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/cli-node@0.1.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/eslint-plugin@0.1.3 + - @backstage/release-manifests@0.0.9 + - @backstage/types@1.0.2 + ## 0.22.7-next.0 ### Patch Changes diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index bad849d283..39bee2ed05 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -58,6 +58,7 @@ Options: --lax --frontend --deprecated + --strict --config -h, --help ``` diff --git a/packages/cli/package.json b/packages/cli/package.json index 9de7b3dbb2..28c5ce7030 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.22.7-next.0", + "version": "0.22.7", "publishConfig": { "access": "public" }, diff --git a/packages/cli/src/commands/config/validate.ts b/packages/cli/src/commands/config/validate.ts index c3d05291e0..c81d82832e 100644 --- a/packages/cli/src/commands/config/validate.ts +++ b/packages/cli/src/commands/config/validate.ts @@ -24,5 +24,6 @@ export default async (opts: OptionValues) => { mockEnv: opts.lax, fullVisibility: !opts.frontend, withDeprecatedKeys: opts.deprecated, + strict: opts.strict, }); }; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index ba11a53cfd..3a40839e25 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -345,6 +345,10 @@ export function registerCommands(program: Command) { .option('--lax', 'Do not require environment variables to be set') .option('--frontend', 'Only validate the frontend configuration') .option('--deprecated', 'Output deprecated configuration settings') + .option( + '--strict', + 'Enable strict config validation, forbidding errors and unknown keys', + ) .option(...configOption) .description( 'Validate that the given configuration loads and matches schema', diff --git a/packages/cli/src/commands/start/startFrontend.ts b/packages/cli/src/commands/start/startFrontend.ts index e066a40e7a..00f7818b41 100644 --- a/packages/cli/src/commands/start/startFrontend.ts +++ b/packages/cli/src/commands/start/startFrontend.ts @@ -32,6 +32,30 @@ interface StartAppOptions { configPaths: string[]; } +function checkReactVersion() { + try { + // Make sure we're looking at the root of the target repo + const reactPkgPath = require.resolve('react/package.json', { + paths: [paths.targetRoot], + }); + const reactPkg = require(reactPkgPath); + if (reactPkg.version.startsWith('16.')) { + console.log( + chalk.yellow( + ` +⚠️ ⚠️ +⚠️ You are using React version 16, which is deprecated for use in Backstage. ⚠️ +⚠️ Please upgrade to React 17 by updating your packages/app dependencies. ⚠️ +⚠️ ⚠️ +`, + ), + ); + } + } catch { + /* ignored */ + } +} + export async function startFrontend(options: StartAppOptions) { if (options.verifyVersions) { const lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock')); @@ -65,6 +89,8 @@ export async function startFrontend(options: StartAppOptions) { } } + checkReactVersion(); + const { name } = await fs.readJson(paths.resolveTarget('package.json')); const config = await loadCliConfig({ args: options.configPaths, diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/lib/config.ts index b34e1280c0..aaf3fcfcb9 100644 --- a/packages/cli/src/lib/config.ts +++ b/packages/cli/src/lib/config.ts @@ -32,6 +32,7 @@ type Options = { withFilteredKeys?: boolean; withDeprecatedKeys?: boolean; fullVisibility?: boolean; + strict?: boolean; }; export async function loadCliConfig(options: Options) { @@ -70,6 +71,7 @@ export async function loadCliConfig(options: Options) { dependencies: localPackageNames, // Include the package.json in the project root if it exists packagePaths: [paths.resolveTargetRoot('package.json')], + noUndeclaredProperties: options.strict, }); const { appConfigs } = await loadConfig({ @@ -93,6 +95,7 @@ export async function loadCliConfig(options: Options) { : ['frontend'], withFilteredKeys: options.withFilteredKeys, withDeprecatedKeys: options.withDeprecatedKeys, + ignoreSchemaErrors: !options.strict, }); const frontendConfig = ConfigReader.fromConfigs(frontendAppConfigs); diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index 9b2d34f957..05e4398bc8 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/config-loader +## 1.3.0 + +### Minor Changes + +- 201206132da: Introduced a new config source system to replace `loadConfig`. There is a new `ConfigSource` interface along with utilities provided by `ConfigSources`, as well as a number of built-in configuration source implementations. The new system is more flexible and makes it easier to create new and reusable sources of configuration, such as loading configuration from secret providers. + + The following is an example of how to load configuration using the default behavior: + + ```ts + const source = ConfigSources.default({ + argv: options?.argv, + remote: options?.remote, + }); + const config = await ConfigSources.toConfig(source); + ``` + + The `ConfigSource` interface looks like this: + + ```ts + export interface ConfigSource { + readConfigData(options?: ReadConfigDataOptions): AsyncConfigSourceIterator; + } + ``` + + It is best implemented using an async iterator: + + ```ts + class MyConfigSource implements ConfigSource { + async *readConfigData() { + yield { + config: [ + { + context: 'example', + data: { backend: { baseUrl: 'http://localhost' } }, + }, + ], + }; + } + } + ``` + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- 473db605a4f: Added a new `noUndeclaredProperties` option to `SchemaLoader` to support enforcing that there are no extra keys when verifying config. +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 1.3.0-next.0 ### Minor Changes diff --git a/packages/config-loader/api-report.md b/packages/config-loader/api-report.md index 1cc353fd4c..8cd469d4d7 100644 --- a/packages/config-loader/api-report.md +++ b/packages/config-loader/api-report.md @@ -180,14 +180,17 @@ export function loadConfigSchema( ): Promise; // @public -export type LoadConfigSchemaOptions = +export type LoadConfigSchemaOptions = ( | { dependencies: string[]; packagePaths?: string[]; } | { serialized: JsonObject; - }; + } +) & { + noUndeclaredProperties?: boolean; +}; // @public export function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7; diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 0aa071c206..d453b40201 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.3.0-next.0", + "version": "1.3.0", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", diff --git a/packages/config-loader/src/schema/compile.ts b/packages/config-loader/src/schema/compile.ts index d193e7fbf2..f9e1a3bf76 100644 --- a/packages/config-loader/src/schema/compile.ts +++ b/packages/config-loader/src/schema/compile.ts @@ -25,6 +25,7 @@ import { CONFIG_VISIBILITIES, ConfigVisibility, } from './types'; +import { SchemaObject } from 'json-schema-traverse'; /** * This takes a collection of Backstage configuration schemas from various @@ -35,6 +36,9 @@ import { */ export function compileConfigSchemas( schemas: ConfigSchemaPackageEntry[], + options?: { + noUndeclaredProperties?: boolean; + }, ): ValidationFunc { // The ajv instance below is stateful and doesn't really allow for additional // output during validation. We work around this by having this extra piece @@ -102,6 +106,18 @@ export function compileConfigSchemas( const merged = mergeConfigSchemas(schemas.map(_ => _.value)); + if (options?.noUndeclaredProperties) { + traverse(merged, (schema: SchemaObject) => { + /** + * The `additionalProperties` key can only be applied to `type: object` in the JSON + * schema. + */ + if (schema?.type === 'object') { + schema.additionalProperties ||= false; + } + }); + } + const validate = ajv.compile(merged); const visibilityBySchemaPath = new Map(); diff --git a/packages/config-loader/src/schema/load.ts b/packages/config-loader/src/schema/load.ts index 0309f64ea0..1a96305ae0 100644 --- a/packages/config-loader/src/schema/load.ts +++ b/packages/config-loader/src/schema/load.ts @@ -32,12 +32,16 @@ import { * @public */ export type LoadConfigSchemaOptions = - | { - dependencies: string[]; - packagePaths?: string[]; - } - | { - serialized: JsonObject; + | ( + | { + dependencies: string[]; + packagePaths?: string[]; + } + | { + serialized: JsonObject; + } + ) & { + noUndeclaredProperties?: boolean; }; function errorsToError(errors: ValidationError[]): Error { @@ -77,7 +81,9 @@ export async function loadConfigSchema( schemas = serialized.schemas as ConfigSchemaPackageEntry[]; } - const validate = compileConfigSchemas(schemas); + const validate = compileConfigSchemas(schemas, { + noUndeclaredProperties: options.noUndeclaredProperties, + }); return { process( diff --git a/packages/config-loader/src/sources/FileConfigSource.test.ts b/packages/config-loader/src/sources/FileConfigSource.test.ts index c6980006c0..61cdeed272 100644 --- a/packages/config-loader/src/sources/FileConfigSource.test.ts +++ b/packages/config-loader/src/sources/FileConfigSource.test.ts @@ -66,7 +66,7 @@ describe('FileConfigSource', () => { setTimeout(() => { tmp.write('a.yaml', 'a: 2'); - }, 10); + }, 100); await expect(readN(source, 2)).resolves.toEqual([ [{ data: { a: 1 }, context: 'a.yaml', path: tmp.resolve('a.yaml') }], @@ -132,7 +132,7 @@ describe('FileConfigSource', () => { setTimeout(() => { tmp.write('x.yaml', '${MY_OTHER_VALUE}'); - }, 10); + }, 100); await expect(readN(source, 2)).resolves.toEqual([ [{ data: { a: '6' }, context: 'a.yaml', path: tmp.resolve('a.yaml') }], @@ -152,7 +152,7 @@ describe('FileConfigSource', () => { setTimeout(() => { tmp.write('x.txt', '9'); - }, 10); + }, 100); await expect(readN(source, 2)).resolves.toEqual([ [{ data: { a: '8' }, context: 'a.yaml', path: tmp.resolve('a.yaml') }], diff --git a/packages/config-loader/src/sources/RemoteConfigSource.ts b/packages/config-loader/src/sources/RemoteConfigSource.ts index ff75060f56..3a8f6bf812 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.ts @@ -149,7 +149,7 @@ export class RemoteConfigSource implements ConfigSource { signal: signal as import('node-fetch').RequestInit['signal'], }); if (!res.ok) { - throw ResponseError.fromResponse(res); + throw await ResponseError.fromResponse(res); } const content = await res.text(); diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index f4179e6fb6..f6df0da032 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/core-app-api +## 1.8.0 + +### Minor Changes + +- c89437db899: The analytics' `navigate` event will now include the route parameters as attributes of the navigate event + +### Patch Changes + +- b645d70034a: Fixed a bug in the Azure auth provider which prevented getting access tokens with multiple scopes for one resource +- 42d817e76ab: Added `FrontendHostDiscovery` for config driven discovery implementation +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + ## 1.8.0-next.1 ### Minor Changes diff --git a/packages/core-app-api/config.d.ts b/packages/core-app-api/config.d.ts index 2de1d96114..e8cc879c90 100644 --- a/packages/core-app-api/config.d.ts +++ b/packages/core-app-api/config.d.ts @@ -117,8 +117,8 @@ export interface Config { }; /** - $ Enable redirect authentication flow type, instead of a popup for authentication - * default value: 'false' + * Enable redirect authentication flow type, instead of a popup for authentication. + * @defaultValue false * @visibility frontend */ enableExperimentalRedirectFlow?: boolean; diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 5d99754068..4416fa99e1 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.8.0-next.1", + "version": "1.8.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts index c71799ed98..1c51dd0698 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts @@ -79,6 +79,16 @@ describe('MicrosoftAuth', () => { 'Requested access token with scopes from multiple Azure resources: one-resource, other-resource. Access tokens can only have a single audience.', ); }); + + it('succeeds when requesting multiple scopes for the same resource', async () => { + const accessTokenPromise = microsoftAuth.getAccessToken( + 'same-resource/one-scope same-resource/other-scope', + ); + + await expect(accessTokenPromise).resolves.toEqual( + 'tokenForOtherResource', + ); + }); }); describe('without a refresh token', () => { diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts index fdffb3fc45..c57c65d830 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts @@ -91,10 +91,15 @@ export default class MicrosoftAuth { } private static resourceForScopes(scope: string): Promise { - const audiences = scope - .split(' ') - .map(MicrosoftAuth.resourceForScope) - .filter(aud => aud !== 'openid'); + const audiences = [ + ...new Set( + scope + .split(' ') + .map(MicrosoftAuth.resourceForScope) + .filter(aud => aud !== 'openid'), + ), + ]; + if (audiences.length > 1) { return Promise.reject( new Error( diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 825b793d2c..8ace83e62b 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/core-components +## 0.13.1 + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style +- e97769f7c0b: Fix accessibility issue on controlled select input on tab navigation + keyboard enter/space action. +- b1f13cb38aa: Fix accessibility issue with Edit Metadata Link on screen readers missing notice about opening in a new tab. +- 26cff1a5dfb: Start capturing sidebar click events in analytics by default. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/version-bridge@1.0.4 + +## 0.13.1-next.1 + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style +- e97769f7c0b: Fix accessibility issue on controlled select input on tab navigation + keyboard enter/space action. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.13.1-next.0 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index cdb5a6e4a8..872808622f 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.13.1-next.0", + "version": "0.13.1", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index be91753ea3..4d58fdfa77 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -188,6 +188,9 @@ export const Link = React.forwardRef( import('./openapi/verify').then(m => m.bulkCommand))); + + openApiCommand + .command('generate [paths...]') + .description( + 'Generates a Typescript file from an OpenAPI yaml spec. For use with the `@backstage/backend-openapi-utils` ApiRouter type.', + ) + .action(lazy(() => import('./openapi/generate').then(m => m.bulkCommand))); +} + export function registerCommands(program: Command) { program .command('api-reports [paths...]') @@ -63,19 +87,7 @@ export function registerCommands(program: Command) { .description('Find inconsistencies in types of all packages and plugins') .action(lazy(() => import('./type-deps/type-deps').then(m => m.default))); - program - .command('schema:openapi:verify [paths...]') - .description( - 'Verify that all OpenAPI schemas are valid and have a matching `schemas/openapi.generated.ts` file.', - ) - .action(lazy(() => import('./openapi/verify').then(m => m.bulkCommand))); - - program - .command('schema:openapi:generate [paths...]') - .description( - 'Generates a Typescript file from an OpenAPI yaml spec. For use with the `@backstage/backend-openapi-utils` ApiRouter type.', - ) - .action(lazy(() => import('./openapi/generate').then(m => m.bulkCommand))); + registerSchemaCommand(program); } // Wraps an action function so that it always exits and handles errors diff --git a/packages/repo-tools/src/commands/openapi/verify.ts b/packages/repo-tools/src/commands/openapi/verify.ts index f6dda66738..4c4f310f73 100644 --- a/packages/repo-tools/src/commands/openapi/verify.ts +++ b/packages/repo-tools/src/commands/openapi/verify.ts @@ -47,7 +47,7 @@ async function verify(directoryPath: string) { if (!isEqual(schema.default, yaml)) { const path = relativePath(cliPaths.targetRoot, directoryPath); throw new Error( - `\`${YAML_SCHEMA_PATH}\` and \`${TS_SCHEMA_PATH}\` do not match. Please run \`yarn backstage-repo-tools schema:openapi:generate ${path}\` to regenerate \`${TS_SCHEMA_PATH}\`.`, + `\`${YAML_SCHEMA_PATH}\` and \`${TS_SCHEMA_PATH}\` do not match. Please run \`yarn backstage-repo-tools schema openapi generate ${path}\` to regenerate \`${TS_SCHEMA_PATH}\`.`, ); } } diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 98bf3668d6..6886f89c11 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,42 @@ # techdocs-cli-embedded-app +## 0.2.82 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/app-defaults@1.3.1 + - @backstage/cli@0.22.7 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/test-utils@1.3.1 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.82-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/app-defaults@1.3.1-next.2 + - @backstage/cli@0.22.7-next.0 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.82-next.1 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 01f5f8128c..fb3715325b 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.82-next.1", + "version": "0.2.82", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 35f3b4bc28..ce88475c7f 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @techdocs/cli +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + ## 1.4.2-next.1 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 8b533b4453..e61401e8ce 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.4.2-next.1", + "version": "1.4.2", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 9fd73a6840..4bebf94052 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/test-utils +## 1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-app-api@1.8.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + +## 1.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/config@1.0.7 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + ## 1.3.1-next.1 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 80d5a2e620..3024b25c05 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.3.1-next.1", + "version": "1.3.1", "publishConfig": { "access": "public" }, diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index e2490f346e..0f8b4819b7 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/theme +## 0.3.0 + +### Minor Changes + +- 98c0c199b15: Updates light theme's primary foreground and `running` status indicator colours to meet WCAG. Previously #2E77D0 changed to #1F5493. + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style + +## 0.3.0-next.0 + +### Minor Changes + +- 98c0c199b15: Updates light theme's primary foreground and `running` status indicator colours to meet WCAG. Previously #2E77D0 changed to #1F5493. + +### Patch Changes + +- 83b45f9df50: Fix accessibility issue with Backstage Table's header style + ## 0.2.19 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index e102c067d7..fbc767fb2f 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.2.19", + "version": "0.3.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/theme/src/baseTheme.ts b/packages/theme/src/baseTheme.ts index 53f3a3ef2b..c0a9022bd0 100644 --- a/packages/theme/src/baseTheme.ts +++ b/packages/theme/src/baseTheme.ts @@ -159,7 +159,6 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides { head: { wordBreak: 'break-word', overflow: 'hidden', - color: theme.palette.textSubtle, fontWeight: 'normal', lineHeight: '1', }, @@ -198,14 +197,10 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides { '&:hover': { color: 'inherit', }, - '&:focus': { - color: 'inherit', - }, }, // Bold font for highlighting selected column active: { fontWeight: 'bold', - color: 'inherit', }, }, MuiListItemText: { diff --git a/packages/theme/src/themes.ts b/packages/theme/src/themes.ts index eb2ef7ce41..23438a1c14 100644 --- a/packages/theme/src/themes.ts +++ b/packages/theme/src/themes.ts @@ -33,7 +33,7 @@ export const lightTheme = createTheme({ ok: '#1DB954', warning: '#FF9800', error: '#E22134', - running: '#2E77D0', + running: '#1F5493', pending: '#FFED51', aborted: '#757575', }, @@ -48,7 +48,7 @@ export const lightTheme = createTheme({ }, }, primary: { - main: '#2E77D0', + main: '#1F5493', }, banner: { info: '#2E77D0', diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 39e8bf7e4c..dd7823c048 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-adr-backend +## 0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-adr-common@0.2.9 + - @backstage/plugin-search-common@1.2.3 + ## 0.3.3-next.1 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index a1f6a859a0..a926239ba7 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.3.3-next.1", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index c3b8806c80..9fddae2588 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-adr-common +## 0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.5 + - @backstage/catalog-model@1.3.0 + - @backstage/plugin-search-common@1.2.3 + ## 0.2.9-next.0 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 0fdf94003a..adbb6bea58 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.2.9-next.0", + "version": "0.2.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index b0ce02fa19..b96e66e9d3 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-adr +## 0.6.0 + +### Minor Changes + +- b12cd5dc221: render SupportButton only if config is set + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-adr-common@0.2.9 + - @backstage/plugin-search-common@1.2.3 + +## 0.5.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.5.1-next.1 ### Patch Changes diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 3202a8c14e..cac6b89fcc 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.5.1-next.1", + "version": "0.6.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx index d136de4717..da575d884f 100644 --- a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx +++ b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx @@ -29,7 +29,7 @@ import { SupportButton, WarningPanel, } from '@backstage/core-components'; -import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { scmIntegrationsApiRef } from '@backstage/integration-react'; import { AdrFilePathFilterFn, @@ -170,6 +170,9 @@ export const EntityAdrContent = (props: { const adrApi = useApi(adrApiRef); const entityHasAdrs = isAdrAvailable(entity); + const config = useApi(configApiRef); + const appSupportConfigured = config?.getOptionalConfig('app.support'); + const { value, loading, error } = useAsync(async () => { const url = getAdrLocationUrl(entity, scmIntegrations); return adrApi.listAdrs(url); @@ -212,7 +215,7 @@ export const EntityAdrContent = (props: { return ( - + {appSupportConfigured && } {!entityHasAdrs && ( diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index 8407f5822e..15c10734de 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-airbrake-backend +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + ## 0.2.18-next.1 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index c57ffa8be9..eaec28f797 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.18-next.1", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index 191207e591..854e9be255 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-airbrake +## 0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/dev-utils@1.0.15 + - @backstage/test-utils@1.3.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/dev-utils@1.0.15-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 6f7f404742..6933bad355 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.18-next.1", + "version": "0.3.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index a20bd80961..e89f981487 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-allure +## 0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.34-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.34-next.1 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 2a98ae1faf..e2f6c7241a 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.34-next.1", + "version": "0.1.34", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index 4195e02248..fc0a434a5e 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-analytics-module-ga +## 0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 31215bd84f..8062c304fa 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.29-next.0", + "version": "0.1.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/analytics-module-ga4/CHANGELOG.md b/plugins/analytics-module-ga4/CHANGELOG.md index 59c03fec0f..c69204bcc0 100644 --- a/plugins/analytics-module-ga4/CHANGELOG.md +++ b/plugins/analytics-module-ga4/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-analytics-module-ga4 +## 0.1.0 + +### Minor Changes + +- 22b46f7f562: Plugin provides Backstage Analytics API for Google Analytics 4. Once installed and configured, analytics events will be sent to GA4 as your users navigate and use your Backstage instance + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga4/package.json b/plugins/analytics-module-ga4/package.json index 5e27228534..dba9d0c8f4 100644 --- a/plugins/analytics-module-ga4/package.json +++ b/plugins/analytics-module-ga4/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga4", - "version": "0.1.0-next.1", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index 368995a369..f9f6958a87 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-apache-airflow +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.11-next.0 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 6d503e972a..4ad427a972 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.11-next.0", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 635b1e2dca..2455e7809c 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-api-docs +## 0.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.9.3-next.1 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 89e65dfcc3..651a606d9c 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.9.3-next.1", + "version": "0.9.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index 174a862d61..9efa02cea9 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-apollo-explorer +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index c1164cf1d6..b28293777d 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.11-next.0", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 1e98f25c64..d89ba0a4ec 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-app-backend +## 0.3.45 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + ## 0.3.45-next.1 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 85602a06e4..9a471f0021 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.45-next.1", + "version": "0.3.45", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index c6ff454a7d..551872232d 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend +## 0.18.3 + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- 473db605a4f: Fix config schema definition. +- 3ffcdac7d07: Added a persistent session store through the database +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.18.3-next.2 + +### Patch Changes + +- 3ffcdac7d07: Added a persistent session store through the database +- Updated dependencies + - @backstage/config@1.0.7 + ## 0.18.3-next.1 ### Patch Changes diff --git a/plugins/auth-backend/config.d.ts b/plugins/auth-backend/config.d.ts index 8d76ca8bf5..c6579e08f8 100644 --- a/plugins/auth-backend/config.d.ts +++ b/plugins/auth-backend/config.d.ts @@ -59,6 +59,7 @@ export interface Config { /** * The available auth-provider options and attributes + * @additionalProperties true */ providers?: { google?: { diff --git a/plugins/auth-backend/migrations/20230428155633_sessions.js b/plugins/auth-backend/migrations/20230428155633_sessions.js new file mode 100644 index 0000000000..49462ac503 --- /dev/null +++ b/plugins/auth-backend/migrations/20230428155633_sessions.js @@ -0,0 +1,52 @@ +/* + * Copyright 2023 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. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // See https://github.com/gx0r/connect-session-knex + // Modeled loosely after https://github.com/gx0r/connect-session-knex/blob/4e0e36a9afbb13c3000a89f5e341f2d2d4339a02/lib/index.js#L114 + // For simplicity we always make the session a string + // Do NOT change around this table or column names; the connect-session-knex library makes assumptions about them + await knex.schema.createTable('sessions', table => { + table.comment('Session data'); + table.string('sid').primary().notNullable().comment('ID of the session'); + table + .text('sess', 'longtext') + .notNullable() + .comment('Session data, JSON serialized'); + table + .timestamp('expired') + .notNullable() + .comment('The point in time when the session expires'); + table.index('sid', 'sessions_sid_idx'); + table.index('expired', 'sessions_expired_idx'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('sessions', table => { + table.dropIndex([], 'sessions_sid_idx'); + table.dropIndex([], 'sessions_expired_idx'); + }); + await knex.schema.dropTable('sessions'); +}; diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 61c3fe9a8d..fb53d9b17f 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.18.3-next.1", + "version": "0.18.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -44,6 +44,7 @@ "@types/express": "^4.17.6", "@types/passport": "^1.0.3", "compression": "^1.7.4", + "connect-session-knex": "^3.0.1", "cookie-parser": "^1.4.5", "cors": "^2.8.5", "express": "^4.17.1", diff --git a/plugins/auth-backend/src/database/AuthDatabase.ts b/plugins/auth-backend/src/database/AuthDatabase.ts new file mode 100644 index 0000000000..97e4236754 --- /dev/null +++ b/plugins/auth-backend/src/database/AuthDatabase.ts @@ -0,0 +1,77 @@ +/* + * Copyright 2023 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 { + DatabaseManager, + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { Knex } from 'knex'; + +const migrationsDir = resolvePackagePath( + '@backstage/plugin-auth-backend', + 'migrations', +); + +/** + * Ensures that a database connection is established exactly once and only when + * asked for, and runs migrations. + */ +export class AuthDatabase { + readonly #database: PluginDatabaseManager; + #promise: Promise | undefined; + + static create(database: PluginDatabaseManager): AuthDatabase { + return new AuthDatabase(database); + } + + /** @internal */ + static forTesting(): AuthDatabase { + const config = new ConfigReader({ + backend: { + database: { + client: 'better-sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }, + }, + }); + const database = DatabaseManager.fromConfig(config).forPlugin('auth'); + return new AuthDatabase(database); + } + + static async runMigrations(knex: Knex): Promise { + await knex.migrate.latest({ + directory: migrationsDir, + }); + } + + private constructor(database: PluginDatabaseManager) { + this.#database = database; + } + + get(): Promise { + this.#promise ??= this.#database.getClient().then(async client => { + if (!this.#database.migrations?.skip) { + await AuthDatabase.runMigrations(client); + } + return client; + }); + + return this.#promise; + } +} diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts index da67a2f88f..cf415c7e13 100644 --- a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts +++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts @@ -14,33 +14,10 @@ * limitations under the License. */ -import Knex, { Knex as KnexType } from 'knex'; -import { DatabaseKeyStore } from './DatabaseKeyStore'; import { DateTime } from 'luxon'; - -function createDatabaseManager( - client: KnexType, - skipMigrations: boolean = false, -) { - return { - getClient: async () => client, - migrations: { - skip: skipMigrations, - }, - }; -} - -function createDB() { - const knex = Knex({ - client: 'better-sqlite3', - connection: ':memory:', - useNullAsDefault: true, - }); - knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { - resource.run('PRAGMA foreign_keys = ON', () => {}); - }); - return knex; -} +import { AuthDatabase } from '../database/AuthDatabase'; +import { DatabaseKeyStore } from './DatabaseKeyStore'; +import { TestDatabases } from '@backstage/backend-test-utils'; const keyBase = { use: 'sig', @@ -48,95 +25,107 @@ const keyBase = { alg: 'Base64', } as const; +jest.setTimeout(60_000); + describe('DatabaseKeyStore', () => { - it('should store a key', async () => { - const client = createDB(); - const store = await DatabaseKeyStore.create({ - database: createDatabaseManager(client), - }); - - const key = { - kid: '123', - ...keyBase, - }; - - await expect(store.listKeys()).resolves.toEqual({ items: [] }); - await store.addKey(key); - - const { items } = await store.listKeys(); - expect(items).toEqual([{ createdAt: expect.anything(), key }]); - expect( - Math.abs( - DateTime.fromJSDate(items[0].createdAt).diffNow('seconds').seconds, - ), - ).toBeLessThan(10); + const databases = TestDatabases.create({ + ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], }); - it('should remove stored keys', async () => { - const client = createDB(); - const store = await DatabaseKeyStore.create({ - database: createDatabaseManager(client), - }); + it.each(databases.eachSupportedId())( + 'should store a key, %p', + async databaseId => { + const knex = await databases.init(databaseId); + await AuthDatabase.runMigrations(knex); - const key1 = { kid: '1', ...keyBase }; - const key2 = { kid: '2', ...keyBase }; - const key3 = { kid: '3', ...keyBase }; + const store = new DatabaseKeyStore(knex); - await store.addKey(key1); - await store.addKey(key2); - await store.addKey(key3); + const key = { + kid: '123', + ...keyBase, + }; - await expect(store.listKeys()).resolves.toEqual({ - items: [ - { key: key1, createdAt: expect.anything() }, - { key: key2, createdAt: expect.anything() }, - { key: key3, createdAt: expect.anything() }, - ], - }); + await expect(store.listKeys()).resolves.toEqual({ items: [] }); + await store.addKey(key); - store.removeKeys(['1']); + const { items } = await store.listKeys(); + expect(items).toEqual([{ createdAt: expect.anything(), key }]); + expect( + Math.abs( + DateTime.fromJSDate(items[0].createdAt).diffNow('seconds').seconds, + ), + ).toBeLessThan(10); + }, + ); - await expect(store.listKeys()).resolves.toEqual({ - items: [ - { key: key2, createdAt: expect.anything() }, - { key: key3, createdAt: expect.anything() }, - ], - }); + it.each(databases.eachSupportedId())( + 'should remove stored keys, %p', + async databaseId => { + const knex = await databases.init(databaseId); + await AuthDatabase.runMigrations(knex); - store.removeKeys(['1', '2']); + const store = new DatabaseKeyStore(knex); - await expect(store.listKeys()).resolves.toEqual({ - items: [{ key: key3, createdAt: expect.anything() }], - }); + const key1 = { kid: '1', ...keyBase }; + const key2 = { kid: '2', ...keyBase }; + const key3 = { kid: '3', ...keyBase }; - store.removeKeys([]); + await store.addKey(key1); + await store.addKey(key2); + await store.addKey(key3); - await expect(store.listKeys()).resolves.toEqual({ - items: [{ key: key3, createdAt: expect.anything() }], - }); + await expect(store.listKeys()).resolves.toEqual({ + items: [ + { key: key1, createdAt: expect.anything() }, + { key: key2, createdAt: expect.anything() }, + { key: key3, createdAt: expect.anything() }, + ], + }); - store.removeKeys(['3', '4']); + await store.removeKeys(['1']); - await expect(store.listKeys()).resolves.toEqual({ - items: [], - }); + await expect(store.listKeys()).resolves.toEqual({ + items: [ + { key: key2, createdAt: expect.anything() }, + { key: key3, createdAt: expect.anything() }, + ], + }); - await store.addKey(key1); - await store.addKey(key2); - await store.addKey(key3); + await store.removeKeys(['1', '2']); - await expect(store.listKeys()).resolves.toEqual({ - items: [ - { key: key1, createdAt: expect.anything() }, - { key: key2, createdAt: expect.anything() }, - { key: key3, createdAt: expect.anything() }, - ], - }); + await expect(store.listKeys()).resolves.toEqual({ + items: [{ key: key3, createdAt: expect.anything() }], + }); - store.removeKeys(['1', '2', '3']); + await store.removeKeys([]); - await expect(store.listKeys()).resolves.toEqual({ - items: [], - }); - }); + await expect(store.listKeys()).resolves.toEqual({ + items: [{ key: key3, createdAt: expect.anything() }], + }); + + await store.removeKeys(['3', '4']); + + await expect(store.listKeys()).resolves.toEqual({ + items: [], + }); + + await store.addKey(key1); + await store.addKey(key2); + await store.addKey(key3); + + await expect(store.listKeys()).resolves.toEqual({ + items: [ + { key: key1, createdAt: expect.anything() }, + { key: key2, createdAt: expect.anything() }, + { key: key3, createdAt: expect.anything() }, + ], + }); + + await store.removeKeys(['1', '2', '3']); + + await expect(store.listKeys()).resolves.toEqual({ + items: [], + }); + }, + ); }); diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.ts index 8039837469..0559b698e9 100644 --- a/plugins/auth-backend/src/identity/DatabaseKeyStore.ts +++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.ts @@ -14,19 +14,10 @@ * limitations under the License. */ -import { - PluginDatabaseManager, - resolvePackagePath, -} from '@backstage/backend-common'; import { Knex } from 'knex'; import { DateTime } from 'luxon'; import { AnyJWK, KeyStore, StoredKey } from './types'; -const migrationsDir = resolvePackagePath( - '@backstage/plugin-auth-backend', - 'migrations', -); - const TABLE = 'signing_keys'; type Row = { @@ -35,10 +26,6 @@ type Row = { key: string; }; -type Options = { - database: PluginDatabaseManager; -}; - const parseDate = (date: string | Date) => { const parsedDate = typeof date === 'string' @@ -55,24 +42,7 @@ const parseDate = (date: string | Date) => { }; export class DatabaseKeyStore implements KeyStore { - static async create(options: Options): Promise { - const { database } = options; - const client = await database.getClient(); - - if (!database.migrations?.skip) { - await client.migrate.latest({ - directory: migrationsDir, - }); - } - - return new DatabaseKeyStore(client); - } - - private readonly client: Knex; - - private constructor(client: Knex) { - this.client = client; - } + constructor(private readonly client: Knex) {} async addKey(key: AnyJWK): Promise { await this.client(TABLE).insert({ diff --git a/plugins/auth-backend/src/identity/KeyStores.test.ts b/plugins/auth-backend/src/identity/KeyStores.test.ts index 375db4698b..6c034eb64b 100644 --- a/plugins/auth-backend/src/identity/KeyStores.test.ts +++ b/plugins/auth-backend/src/identity/KeyStores.test.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import { DatabaseManager } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; - -import { MemoryKeyStore } from './MemoryKeyStore'; +import { AuthDatabase } from '../database/AuthDatabase'; import { DatabaseKeyStore } from './DatabaseKeyStore'; import { FirestoreKeyStore } from './FirestoreKeyStore'; import { KeyStores } from './KeyStores'; +import { MemoryKeyStore } from './MemoryKeyStore'; +import { getVoidLogger } from '@backstage/backend-common'; describe('KeyStores', () => { const defaultConfigOptions = { @@ -34,7 +34,10 @@ describe('KeyStores', () => { it('reads auth section from config', async () => { const configSpy = jest.spyOn(defaultConfig, 'getOptionalConfig'); - const keyStore = await KeyStores.fromConfig(defaultConfig); + const keyStore = await KeyStores.fromConfig(defaultConfig, { + logger: getVoidLogger(), + database: AuthDatabase.forTesting(), + }); expect(keyStore).toBeInstanceOf(MemoryKeyStore); expect(configSpy).toHaveBeenCalledWith('auth.keyStore'); @@ -46,18 +49,10 @@ describe('KeyStores', () => { }); it('can handle without auth config', async () => { - const config = new ConfigReader({ - backend: { - database: { - client: 'better-sqlite3', - connection: ':memory:', - }, - }, + const keyStore = await KeyStores.fromConfig(new ConfigReader({}), { + logger: getVoidLogger(), + database: AuthDatabase.forTesting(), }); - const database = - DatabaseManager.fromConfig(config).forPlugin('auth-backend'); - const keyStore = await KeyStores.fromConfig(config, { database }); - expect(keyStore).toBeInstanceOf(DatabaseKeyStore); }); @@ -82,7 +77,10 @@ describe('KeyStores', () => { }, }; const config = new ConfigReader(configOptions); - const keyStore = await KeyStores.fromConfig(config); + const keyStore = await KeyStores.fromConfig(config, { + logger: getVoidLogger(), + database: AuthDatabase.forTesting(), + }); expect(keyStore).toBeInstanceOf(FirestoreKeyStore); expect(createSpy).toHaveBeenCalledWith( diff --git a/plugins/auth-backend/src/identity/KeyStores.ts b/plugins/auth-backend/src/identity/KeyStores.ts index e29b4b6fc4..4cd8f91842 100644 --- a/plugins/auth-backend/src/identity/KeyStores.ts +++ b/plugins/auth-backend/src/identity/KeyStores.ts @@ -14,20 +14,20 @@ * limitations under the License. */ -import { Logger } from 'winston'; import { pickBy } from 'lodash'; +import { Logger } from 'winston'; -import { PluginDatabaseManager } from '@backstage/backend-common'; import { Config } from '@backstage/config'; +import { AuthDatabase } from '../database/AuthDatabase'; import { DatabaseKeyStore } from './DatabaseKeyStore'; -import { MemoryKeyStore } from './MemoryKeyStore'; import { FirestoreKeyStore } from './FirestoreKeyStore'; +import { MemoryKeyStore } from './MemoryKeyStore'; import { KeyStore } from './types'; type Options = { - logger?: Logger; - database?: PluginDatabaseManager; + logger: Logger; + database: AuthDatabase; }; export class KeyStores { @@ -37,23 +37,16 @@ export class KeyStores { * * @returns a KeyStore store */ - static async fromConfig( - config: Config, - options?: Options, - ): Promise { - const { logger, database } = options ?? {}; + static async fromConfig(config: Config, options: Options): Promise { + const { logger, database } = options; const ks = config.getOptionalConfig('auth.keyStore'); const provider = ks?.getOptionalString('provider') ?? 'database'; - logger?.info(`Configuring "${provider}" as KeyStore provider`); + logger.info(`Configuring "${provider}" as KeyStore provider`); if (provider === 'database') { - if (!database) { - throw new Error('This KeyStore provider requires a database'); - } - - return await DatabaseKeyStore.create({ database }); + return new DatabaseKeyStore(await database.get()); } if (provider === 'memory') { diff --git a/plugins/auth-backend/src/migrations.test.ts b/plugins/auth-backend/src/migrations.test.ts new file mode 100644 index 0000000000..194bbbf44c --- /dev/null +++ b/plugins/auth-backend/src/migrations.test.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2022 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'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import fs from 'fs'; + +const migrationsDir = `${__dirname}/../migrations`; +const migrationsFiles = fs.readdirSync(migrationsDir).sort(); + +async function migrateUpOnce(knex: Knex): Promise { + await knex.migrate.up({ directory: migrationsDir }); +} + +async function migrateDownOnce(knex: Knex): Promise { + await knex.migrate.down({ directory: migrationsDir }); +} + +async function migrateUntilBefore(knex: Knex, target: string): Promise { + const index = migrationsFiles.indexOf(target); + if (index === -1) { + throw new Error(`Migration ${target} not found`); + } + for (let i = 0; i < index; i++) { + await migrateUpOnce(knex); + } +} + +jest.setTimeout(60_000); + +describe('migrations', () => { + const databases = TestDatabases.create({ + ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + }); + + it.each(databases.eachSupportedId())( + '20230428155633_sessions.js, %p', + async databaseId => { + const knex = await databases.init(databaseId); + + await migrateUntilBefore(knex, '20230428155633_sessions.js'); + await migrateUpOnce(knex); + + // Ensure that large cookies are supported + const data = `{"cookie":"${'a'.repeat(100_000)}"}`; + await knex + .insert({ sid: 'abc', expired: knex.fn.now(), sess: data }) + .into('sessions'); + await knex + .insert({ sid: 'def', expired: knex.fn.now(), sess: data }) + .into('sessions'); + + await expect(knex('sessions').orderBy('sid', 'asc')).resolves.toEqual([ + { sid: 'abc', expired: expect.anything(), sess: data }, + { sid: 'def', expired: expect.anything(), sess: data }, + ]); + + await migrateDownOnce(knex); + + await knex.destroy(); + }, + ); +}); diff --git a/plugins/auth-backend/src/providers/cloudflare-access/provider.ts b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts index 0d8f736550..6313276508 100644 --- a/plugins/auth-backend/src/providers/cloudflare-access/provider.ts +++ b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts @@ -227,7 +227,7 @@ export class CloudflareAccessAuthProvider implements AuthProviderRouteHandlers { { headers }, ); if (!res.ok) { - throw ResponseError.fromResponse(res); + throw await ResponseError.fromResponse(res); } const cfIdentity = await res.json(); return cfIdentity as unknown as CloudflareAccessIdentityProfile; diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index 8013777415..2996ff68be 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -32,9 +32,11 @@ import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { createOidcRouter, TokenFactory, KeyStores } from '../identity'; import session from 'express-session'; +import connectSessionKnex from 'connect-session-knex'; import passport from 'passport'; import { Minimatch } from 'minimatch'; import { CatalogAuthResolverContext } from '../lib/resolvers'; +import { AuthDatabase } from '../database/AuthDatabase'; /** @public */ export type ProviderFactories = { [s: string]: AuthProviderFactory }; @@ -70,7 +72,11 @@ export async function createRouter( const appUrl = config.getString('app.baseUrl'); const authUrl = await discovery.getExternalBaseUrl('auth'); - const keyStore = await KeyStores.fromConfig(config, { logger, database }); + const authDb = AuthDatabase.create(database); + const keyStore = await KeyStores.fromConfig(config, { + logger, + database: authDb, + }); const keyDurationSeconds = 3600; const tokenIssuer = new TokenFactory({ @@ -84,14 +90,18 @@ export async function createRouter( const secret = config.getOptionalString('auth.session.secret'); if (secret) { router.use(cookieParser(secret)); - // TODO: Configure the server-side session storage. The default MemoryStore is not designed for production const enforceCookieSSL = authUrl.startsWith('https'); + const KnexSessionStore = connectSessionKnex(session); router.use( session({ secret, saveUninitialized: false, resave: false, cookie: { secure: enforceCookieSSL ? 'auto' : false }, + store: new KnexSessionStore({ + createtable: false, + knex: await authDb.get(), + }), }), ); router.use(passport.initialize()); diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 7cb9f4cc64..e299198f8f 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-node +## 0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.2.14-next.1 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 1d8e71a4c0..25bcda593a 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.14-next.1", + "version": "0.2.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 3dd206ae66..232347e752 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-azure-devops-backend +## 0.3.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.3.24-next.1 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index f28bfa5cb4..2a0f3b76a5 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.24-next.1", + "version": "0.3.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index a0328bcb22..20bbec23b4 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-azure-devops +## 0.3.0 + +### Minor Changes + +- 877df261085: The getBuildRuns function now checks contains multiple comma-separated builds and splits them to send multiple requests for each and concatenates the results. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-azure-devops-common@0.3.0 + +## 0.3.0-next.2 + +### Minor Changes + +- 877df261085: The getBuildRuns function now checks contains multiple comma-separated builds and splits them to send multiple requests for each and concatenates the results. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.9-next.1 ### Patch Changes diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 5079fa4f16..7eeae09813 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -70,7 +70,7 @@ dev.azure.com/project: dev.azure.com/build-definition: ``` -In this case `` will be the name of your Team Project and `` will be the name of the Build Definition you would like to see Builds for. If the Build Definition name has spaces in it make sure to put quotes around it +In this case `` will be the name of your Team Project and `` will be the name of the Build Definition you would like to see Builds for, and it's possible to add more Builds separated by a comma. If the Build Definition name has spaces in it make sure to put quotes around it. ### Azure Pipelines Component diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 914cc9a4ba..99122b62db 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.2.9-next.1", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index 68d8896538..a202008798 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -120,7 +120,23 @@ export class AzureDevOpsClient implements AzureDevOpsApi { queryString.append('repoName', repoName); } if (definitionName) { - queryString.append('definitionName', definitionName); + const definitionNames = definitionName.split(','); + if (definitionNames.length > 1) { + const buildRuns: BuildRun[] = []; + for (const name of definitionNames) { + queryString.set('definitionName', name.trim()); + if (options?.top) { + queryString.set('top', options.top.toString()); + } + const urlSegment = `builds/${encodeURIComponent( + projectName, + )}?${queryString}`; + const items = await this.get(urlSegment); + buildRuns.push(...items); + } + return { items: buildRuns }; + } + queryString.append('definitionName', definitionName.trim()); } if (options?.top) { queryString.append('top', options.top.toString()); diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index 9c25a70214..d8b123dec1 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-azure-sites-backend +## 0.1.7 + +### Patch Changes + +- d66d4f916aa: Updated URL to `/health` and corrected typos in the `README.md` +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-azure-sites-common@0.1.0 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/azure-sites-backend/README.md b/plugins/azure-sites-backend/README.md index 0d44b9a4e4..23152f9760 100644 --- a/plugins/azure-sites-backend/README.md +++ b/plugins/azure-sites-backend/README.md @@ -2,7 +2,7 @@ Simple plugin that proxies requests to the Azure Portal API through Azure SDK JavaScript libraries. -_Inspired by [roadie.io AWS Lamda plugin](https://roadie.io/backstage/plugins/aws-lambda/)_ +_Inspired by [roadie.io AWS Lambda plugin](https://roadie.io/backstage/plugins/aws-lambda/)_ ## Setup @@ -65,7 +65,7 @@ Here's how to get the backend plugin up and running: ```ts import azure from './plugins/azure'; - // Removed for clairty... + // Removed for clarity... async function main() { // ... @@ -82,4 +82,4 @@ Here's how to get the backend plugin up and running: 4. Now run `yarn start-backend` from the repo root. -5. Finally, open `http://localhost:7007/api/azure/health` in a browser, it should return `{"status":"ok"}`. +5. Finally, open `http://localhost:7007/api/azure-sites/health` in a browser, it should return `{"status":"ok"}`. diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index a58459d2aa..61c23a4b0f 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index 1eea015834..bc7184c9ca 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-azure-sites +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-azure-sites-common@0.1.0 + +## 0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 8863e76dae..44775bcab4 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index 50bf55c918..e15a74e3de 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-badges-backend +## 0.2.0 + +### Minor Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +### Patch Changes + +- 0cd552c28d8: Removed some unused dependencies +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## 0.2.0-next.2 + +### Minor Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + ## 0.1.39-next.1 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 9c235255e5..f2db6ef5c5 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.39-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -55,9 +55,6 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", "@types/node": "*", "cross-fetch": "^3.1.5" }, diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index b4a0e6aec6..1ec81cb321 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-badges +## 0.2.42 + +### Patch Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.42-next.2 + +### Patch Changes + +- a0108c49774: Fixing badges-backend plugin to get a token from the TokenManager instead of parsing the request header. Hence, it's now possible to disable the authMiddleware for the badges-backend plugin to expose publicly the badges. + + Implementing an obfuscation feature to protect an open badges endpoint from being enumerated. The feature is disabled by default and the change is compatible with the previous version. + + **BREAKING**: `createRouter` now require that `tokenManager`, `logger`, and `identityApi`, are passed in as options. + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.42-next.1 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 714de3e3fb..fcfb55c386 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.42-next.1", + "version": "0.2.42", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index 11d820a334..da83be709c 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-bazaar-backend +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 60e549655e..9dd25233c6 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.2.8-next.1", + "version": "0.2.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index 298c684d3e..4b1a86deb9 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-bazaar +## 0.2.8 + +### Patch Changes + +- 900880ab7c3: Fixed `validateDOMNesting` warnings +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/cli@0.22.7 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.8-next.2 + +### Patch Changes + +- 900880ab7c3: Fixed `validateDOMNesting` warnings +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/cli@0.22.7-next.0 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index c61db47231..d8d334b426 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.8-next.1", + "version": "0.2.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index c3c31ed392..04b2cc787b 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.4.5 + ## 0.2.6-next.0 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index 7bf2c5791e..a63b9588fb 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", "description": "Common functionalities for bitbucket-cloud plugins", - "version": "0.2.6-next.0", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 1ef42a6bbe..069fc0ca6e 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-bitrise +## 0.1.45 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.45-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.45-next.1 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 1b3740a058..fe62603226 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.45-next.1", + "version": "0.1.45", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index f7ffc5e63c..029ab14592 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.2.0 + +### Minor Changes + +- 1a3b5f1e390: **BREAKING**: AwsOrganizationCloudAccountProcessor.fromConfig now returns a promise instead of the instance directly. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## 0.1.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/config@1.0.7 + ## 0.1.19-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/api-report.md b/plugins/catalog-backend-module-aws/api-report.md index 491dbf497e..83b072061b 100644 --- a/plugins/catalog-backend-module-aws/api-report.md +++ b/plugins/catalog-backend-module-aws/api-report.md @@ -3,11 +3,12 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AwsCredentialIdentity } from '@aws-sdk/types'; +import { AwsCredentialsManager } from '@backstage/integration-aws-node'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; -import { Credentials } from 'aws-sdk'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { LocationSpec } from '@backstage/plugin-catalog-common'; @@ -19,11 +20,16 @@ import { UrlReader } from '@backstage/backend-common'; // @public export type AWSCredentialFactory = ( awsAccountId: string, -) => Promise; +) => Promise; // @public export class AwsEKSClusterProcessor implements CatalogProcessor { - constructor(options: { credentialsFactory?: AWSCredentialFactory }); + constructor(options: { + credentialsFactory?: AWSCredentialFactory; + credentialsManager?: AwsCredentialsManager; + }); + // (undocumented) + static fromConfig(configRoot: Config): AwsEKSClusterProcessor; // (undocumented) getProcessorName(): string; // (undocumented) @@ -44,7 +50,7 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { options: { logger: Logger; }, - ): AwsOrganizationCloudAccountProcessor; + ): Promise; // (undocumented) getProcessorName(): string; // (undocumented) diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 73bd5123d2..a5e0aad55b 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.19-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@aws-sdk/client-s3": "^3.208.0", + "@aws-sdk/client-eks": "^3.310.0", + "@aws-sdk/client-organizations": "^3.310.0", + "@aws-sdk/client-s3": "^3.310.0", + "@aws-sdk/credential-providers": "^3.310.0", + "@aws-sdk/middleware-endpoint": "^3.310.0", + "@aws-sdk/types": "^3.310.0", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", @@ -53,23 +58,23 @@ "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", + "@backstage/integration-aws-node": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/types": "workspace:^", - "aws-sdk": "^2.840.0", "lodash": "^4.17.21", "p-limit": "^3.0.2", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@aws-sdk/util-stream-node": "^3.208.0", + "@aws-sdk/util-stream-node": "^3.310.0", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "aws-sdk-client-mock": "^2.0.0", - "aws-sdk-mock": "^5.2.1", + "aws-sdk-client-mock-jest": "^2.0.0", "luxon": "^3.0.0", "yaml": "^2.0.0" }, diff --git a/plugins/catalog-backend-module-aws/src/credentials/AwsCredentials.ts b/plugins/catalog-backend-module-aws/src/credentials/AwsCredentials.ts deleted file mode 100644 index fded78aed4..0000000000 --- a/plugins/catalog-backend-module-aws/src/credentials/AwsCredentials.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2022 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 aws, { Credentials } from 'aws-sdk'; -import { CredentialsOptions } from 'aws-sdk/lib/credentials'; - -export class AwsCredentials { - /** - * If accessKeyId and secretAccessKey are missing, the DefaultAWSCredentialsProviderChain will be used: - * https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html - */ - static create( - config: { - accessKeyId?: string; - secretAccessKey?: string; - roleArn?: string; - externalId?: string; - }, - roleSessionName: string, - ): Credentials | CredentialsOptions | undefined { - if (!config) { - return undefined; - } - - const accessKeyId = config.accessKeyId; - const secretAccessKey = config.secretAccessKey; - let explicitCredentials: Credentials | undefined; - - if (accessKeyId && secretAccessKey) { - explicitCredentials = new Credentials({ - accessKeyId, - secretAccessKey, - }); - } - - const roleArn = config.roleArn; - if (roleArn) { - return new aws.ChainableTemporaryCredentials({ - masterCredentials: explicitCredentials, - params: { - RoleArn: roleArn, - RoleSessionName: roleSessionName, - ExternalId: config.externalId, - }, - }); - } - - return explicitCredentials; - } -} diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.test.ts b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.test.ts index ecf3b1a961..6cec6ed66d 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.test.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.test.ts @@ -15,24 +15,28 @@ */ import { AwsEKSClusterProcessor } from './AwsEKSClusterProcessor'; -import AWSMock from 'aws-sdk-mock'; -import aws from 'aws-sdk'; +import { mockClient } from 'aws-sdk-client-mock'; +import { + ListClustersResponse, + DescribeClusterResponse, + ListClustersCommand, + DescribeClusterCommand, + EKSClient, +} from '@aws-sdk/client-eks'; describe('AwsEKSClusterProcessor', () => { - AWSMock.setSDKInstance(aws); - describe('readLocation', () => { const processor = new (AwsEKSClusterProcessor as any)({}); const location = { type: 'aws-eks', target: '957140518395/us-west-2' }; const emit = jest.fn(); it('generates cluster correctly', async () => { - const clusters: aws.EKS.Types.ListClustersResponse = { + const clusters: ListClustersResponse = { clusters: ['backstage-test'], nextToken: undefined, }; - const cluster: aws.EKS.Types.DescribeClusterResponse = { + const cluster: DescribeClusterResponse = { cluster: { name: 'backstage-test', arn: 'arn:aws:1', @@ -42,9 +46,10 @@ describe('AwsEKSClusterProcessor', () => { }, }, }; + const mock = mockClient(EKSClient); - AWSMock.mock('EKS', 'listClusters', clusters); - AWSMock.mock('EKS', 'describeCluster', cluster); + mock.on(ListClustersCommand).resolves(clusters); + mock.on(DescribeClusterCommand).resolves(cluster); await processor.readLocation(location, false, emit); diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts index 05c85c7426..4a19b9eb7f 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsEKSClusterProcessor.ts @@ -24,8 +24,14 @@ import { ANNOTATION_KUBERNETES_API_SERVER_CA, ANNOTATION_KUBERNETES_AUTH_PROVIDER, } from '@backstage/plugin-kubernetes-common'; -import { Credentials, EKS } from 'aws-sdk'; +import { EKS } from '@aws-sdk/client-eks'; import { AWSCredentialFactory } from '../types'; +import { AwsCredentialIdentity, Provider } from '@aws-sdk/types'; +import { + AwsCredentialsManager, + DefaultAwsCredentialsManager, +} from '@backstage/integration-aws-node'; +import { Config } from '@backstage/config'; const ACCOUNTID_ANNOTATION: string = 'amazonaws.com/account-id'; const ARN_ANNOTATION: string = 'amazonaws.com/arn'; @@ -39,9 +45,22 @@ const ARN_ANNOTATION: string = 'amazonaws.com/arn'; */ export class AwsEKSClusterProcessor implements CatalogProcessor { private credentialsFactory?: AWSCredentialFactory; + private credentialsManager?: AwsCredentialsManager; - constructor(options: { credentialsFactory?: AWSCredentialFactory }) { + static fromConfig(configRoot: Config): AwsEKSClusterProcessor { + const awsCredentaislManager = + DefaultAwsCredentialsManager.fromConfig(configRoot); + return new AwsEKSClusterProcessor({ + credentialsManager: awsCredentaislManager, + }); + } + + constructor(options: { + credentialsFactory?: AWSCredentialFactory; + credentialsManager?: AwsCredentialsManager; + }) { this.credentialsFactory = options.credentialsFactory; + this.credentialsManager = options.credentialsManager; } getProcessorName(): string { @@ -73,20 +92,30 @@ export class AwsEKSClusterProcessor implements CatalogProcessor { ); } - let credentials: Credentials | undefined; + let credentials: AwsCredentialIdentity | undefined; if (this.credentialsFactory) { credentials = await this.credentialsFactory(accountId); } - const eksClient = new EKS({ credentials, region }); - const clusters = await eksClient.listClusters({}).promise(); + let providerFunction: (() => Provider) | undefined; + if (this.credentialsManager) { + const credentialsProvider = + await this.credentialsManager.getCredentialProvider({ accountId }); + providerFunction = () => credentialsProvider.sdkCredentialProvider; + } + + const eksClient = new EKS({ + credentials, + credentialDefaultProvider: providerFunction, + }); + const clusters = await eksClient.listClusters({}); if (clusters.clusters === undefined) { return true; } const results = clusters.clusters - .map(cluster => eksClient.describeCluster({ name: cluster }).promise()) + .map(cluster => eksClient.describeCluster({ name: cluster })) .map(async describedClusterPromise => { const describedCluster = await describedClusterPromise; if (describedCluster.cluster) { diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.test.ts b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.test.ts index b9b8ba7741..458a1f3531 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.test.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.test.ts @@ -14,7 +14,13 @@ * limitations under the License. */ +import { mockClient } from 'aws-sdk-client-mock'; +import 'aws-sdk-client-mock-jest'; import { AwsOrganizationCloudAccountProcessor } from './AwsOrganizationCloudAccountProcessor'; +import { + ListAccountsCommand, + OrganizationsClient, +} from '@aws-sdk/client-organizations'; describe('AwsOrganizationCloudAccountProcessor', () => { describe('readLocation', () => { @@ -23,26 +29,21 @@ describe('AwsOrganizationCloudAccountProcessor', () => { }); const location = { type: 'aws-cloud-accounts', target: '' }; const emit = jest.fn(); - const listAccounts = jest.fn(); + const mock = mockClient(OrganizationsClient); - processor.organizations.listAccounts = listAccounts; - afterEach(() => jest.resetAllMocks()); + afterEach(() => { + jest.resetAllMocks(); + }); it('generates component entities for accounts', async () => { - listAccounts.mockImplementation(() => { - return { - async promise() { - return { - Accounts: [ - { - Arn: 'arn:aws:organizations::192594491037:account/o-1vl18kc5a3/957140518395', - Name: 'testaccount', - }, - ], - NextToken: undefined, - }; + mock.on(ListAccountsCommand).resolves({ + Accounts: [ + { + Arn: 'arn:aws:organizations::192594491037:account/o-1vl18kc5a3/957140518395', + Name: 'testaccount', }, - }; + ], + NextToken: undefined, }); await processor.readLocation(location, false, emit); expect(emit).toHaveBeenCalledWith({ @@ -74,24 +75,18 @@ describe('AwsOrganizationCloudAccountProcessor', () => { type: 'aws-cloud-accounts', target: 'o-1vl18kc5a3', }; - listAccounts.mockImplementation(() => { - return { - async promise() { - return { - Accounts: [ - { - Arn: 'arn:aws:organizations::192594491037:account/o-1vl18kc5a3/957140518395', - Name: 'testaccount', - }, - { - Arn: 'arn:aws:organizations::192594491037:account/o-zzzzzzzzz/957140518395', - Name: 'testaccount2', - }, - ], - NextToken: undefined, - }; + mock.on(ListAccountsCommand).resolves({ + Accounts: [ + { + Arn: 'arn:aws:organizations::192594491037:account/o-1vl18kc5a3/957140518395', + Name: 'testaccount', }, - }; + { + Arn: 'arn:aws:organizations::192594491037:account/o-zzzzzzzzz/957140518395', + Name: 'testaccount2', + }, + ], + NextToken: undefined, }); await processor.readLocation(locationTest, false, emit); expect(emit).toHaveBeenCalledTimes(1); diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts index c0ba1e3e98..264fa7a50d 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsOrganizationCloudAccountProcessor.ts @@ -22,13 +22,17 @@ import { processingResult, } from '@backstage/plugin-catalog-node'; import { LocationSpec } from '@backstage/plugin-catalog-common'; -import AWS, { Credentials, Organizations } from 'aws-sdk'; -import { Account, ListAccountsResponse } from 'aws-sdk/clients/organizations'; -import { Logger } from 'winston'; import { - AwsOrganizationProviderConfig, - readAwsOrganizationConfig, -} from '../awsOrganization/config'; + Account, + ListAccountsResponse, + Organizations, +} from '@aws-sdk/client-organizations'; +import { Logger } from 'winston'; +import { readAwsOrganizationConfig } from '../awsOrganization/config'; +import { + AwsCredentialProvider, + DefaultAwsCredentialsManager, +} from '@backstage/integration-aws-node'; const AWS_ORGANIZATION_REGION = 'us-east-1'; const LOCATION_TYPE = 'aws-cloud-accounts'; @@ -47,39 +51,31 @@ const ORGANIZATION_ANNOTATION = 'amazonaws.com/organization-id'; */ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { private readonly organizations: Organizations; - private readonly provider: AwsOrganizationProviderConfig; + private readonly logger: Logger; - static fromConfig(config: Config, options: { logger: Logger }) { + static async fromConfig(config: Config, options: { logger: Logger }) { const c = config.getOptionalConfig('catalog.processors.awsOrganization'); - return new AwsOrganizationCloudAccountProcessor({ - ...options, - provider: c ? readAwsOrganizationConfig(c) : {}, + const orgConfig = c ? readAwsOrganizationConfig(c) : undefined; + const awsCredentialsManager = + DefaultAwsCredentialsManager.fromConfig(config); + const credProvider = await awsCredentialsManager.getCredentialProvider({ + arn: orgConfig?.roleArn, }); - } - - private static buildCredentials( - config: AwsOrganizationProviderConfig, - ): Credentials | undefined { - const roleArn = config.roleArn; - if (!roleArn) { - return undefined; - } - - return new AWS.ChainableTemporaryCredentials({ - params: { - RoleSessionName: 'backstage-aws-organization-processor', - RoleArn: roleArn, - }, - }); - } - - private constructor(options: { provider: AwsOrganizationProviderConfig }) { - this.provider = options.provider; - const credentials = AwsOrganizationCloudAccountProcessor.buildCredentials( - this.provider, + return new AwsOrganizationCloudAccountProcessor( + credProvider, + options.logger, ); - this.organizations = new AWS.Organizations({ - credentials, + } + + private constructor( + private readonly credProvider: AwsCredentialProvider, + logger: Logger, + ) { + this.logger = logger?.child({ + target: this.getProcessorName(), + }); + this.organizations = new Organizations({ + credentialDefaultProvider: () => this.credProvider.sdkCredentialProvider, region: AWS_ORGANIZATION_REGION, }); // Only available in us-east-1 } @@ -97,6 +93,8 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { return false; } + this.logger?.info('Discovering AWS Organization Account objects'); + (await this.getAwsAccounts()) .map(account => this.mapAccountToComponent(account)) .filter(entity => { @@ -143,9 +141,8 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { let nextToken = undefined; while (isInitialAttempt || nextToken) { isInitialAttempt = false; - const orgAccounts: ListAccountsResponse = await this.organizations - .listAccounts({ NextToken: nextToken }) - .promise(); + const orgAccounts: ListAccountsResponse = + await this.organizations.listAccounts({ NextToken: nextToken }); if (orgAccounts.Accounts) { awsAccounts = awsAccounts.concat(orgAccounts.Accounts); } diff --git a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.test.ts b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.test.ts index 821fb6d4f4..e9e17ad76a 100644 --- a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.test.ts +++ b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.test.ts @@ -23,8 +23,9 @@ import { import { ConfigReader } from '@backstage/config'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { AwsS3EntityProvider } from './AwsS3EntityProvider'; -import aws from 'aws-sdk'; -import AWSMock from 'aws-sdk-mock'; +import { mockClient } from 'aws-sdk-client-mock'; +import 'aws-sdk-client-mock-jest'; +import { ListObjectsV2Command, S3Client } from '@aws-sdk/client-s3'; class PersistingTaskRunner implements TaskRunner { private tasks: TaskInvocationDefinition[] = []; @@ -42,38 +43,39 @@ class PersistingTaskRunner implements TaskRunner { const logger = getVoidLogger(); describe('AwsS3EntityProvider', () => { - AWSMock.setSDKInstance(aws); - const createObjectList = (keys: string[]): aws.S3.ObjectList => { + const createObjectList = (keys: string[]) => { const objects = keys.map(key => { return { Key: key, - } as aws.S3.Types.Object; + }; }); - - return objects as aws.S3.ObjectList; + return objects; }; const keys = ['key1.yaml', 'key2.yaml', 'key3.yaml', 'key 4.yaml']; + const mock = mockClient(S3Client); - AWSMock.mock('S3', 'listObjectsV2', async req => { - const prefix = req.Prefix ?? ''; + beforeEach(() => { + mock.on(ListObjectsV2Command).callsFake(async req => { + const prefix = req.Prefix ?? ''; + + if (!req.ContinuationToken) { + return { + Contents: createObjectList( + keys + .slice(0, Math.ceil(keys.length / 2)) + .map(key => `${prefix}${key}`), + ), + NextContinuationToken: 'next-token', + }; + } - if (!req.ContinuationToken) { return { Contents: createObjectList( - keys - .slice(0, Math.ceil(keys.length / 2)) - .map(key => `${prefix}${key}`), + keys.slice(Math.ceil(keys.length / 2)).map(key => `${prefix}${key}`), ), - NextContinuationToken: 'next-token', - } as aws.S3.Types.ListObjectsV2Output; - } - - return { - Contents: createObjectList( - keys.slice(Math.ceil(keys.length / 2)).map(key => `${prefix}${key}`), - ), - } as aws.S3.Types.ListObjectsV2Output; + }; + }); }); afterEach(() => { @@ -103,7 +105,9 @@ describe('AwsS3EntityProvider', () => { }); const schedulingConfig: Record = {}; - + const normalizedExpectedBaseUrl = expectedBaseUrl.endsWith('/') + ? expectedBaseUrl + : `${expectedBaseUrl}/`; const schedule = new PersistingTaskRunner(); const entityProviderConnection: EntityProviderConnection = { applyMutation: jest.fn(), @@ -131,7 +135,7 @@ describe('AwsS3EntityProvider', () => { await (taskDef.fn as () => Promise)(); const expectedEntities = keys.map(key => { - const url = encodeURI(`${expectedBaseUrl}${key}`); + const url = encodeURI(`${normalizedExpectedBaseUrl}${key}`); return { entity: { apiVersion: 'backstage.io/v1alpha1', @@ -161,6 +165,25 @@ describe('AwsS3EntityProvider', () => { // eslint-disable-next-line jest/expect-expect it('apply full update on scheduled execution', async () => { + return expectMutation( + 'regionalStatic', + { + bucketName: 'bucket-1', + prefix: 'sub/dir/', + region: 'eu-west-1', + }, + 'https://bucket-1.s3.eu-west-1.amazonaws.com/sub/dir/', + { + 'key1.yaml': 'generated-8ece85ad90200c6577b99f553dcbedde05fa34bb', + 'key2.yaml': 'generated-6b54c6aaa44696f5e91ce0f54fb27bf837549d11', + 'key3.yaml': 'generated-88c703cf1aa66913db4033b029adc0b174574646', + 'key 4.yaml': 'generated-2b7e068bb4ec818c14f179a1e721843fc2dbc5f9', + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('apply full update on scheduled execution force path style', async () => { return expectMutation( 'regionalStatic', { @@ -175,11 +198,72 @@ describe('AwsS3EntityProvider', () => { 'key3.yaml': 'generated-8d75f78ed9fa618ce433b226dc24eeab441f3a2d', 'key 4.yaml': 'generated-1e0249dcb5805fc2ce6ac2d3c4d2a3ef4f1270c0', }, + { + s3ForcePathStyle: true, + }, ); }); // eslint-disable-next-line jest/expect-expect - it('us-east-1 has region-less URLs', async () => { + it('apply full update on scheduled execution no prefix', async () => { + return expectMutation( + 'regionalStatic', + { + bucketName: 'bucket-1', + region: 'eu-west-1', + }, + 'https://bucket-1.s3.eu-west-1.amazonaws.com/', + { + 'key1.yaml': 'generated-ac6d99e56e0fbd6bf3719a5182f37bfa84b1cddc', + 'key2.yaml': 'generated-cc3e1145496cd95bf3898687bb5b7d2991a7b7fd', + 'key3.yaml': 'generated-a197557b0cb89d14ac1297231ed930bd4c40b664', + 'key 4.yaml': 'generated-a774e6c1d1c7ee511b7d79ebb99b08a39cf439c4', + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('apply full update on scheduled execution force path style no prefix', async () => { + return expectMutation( + 'regionalStatic', + { + bucketName: 'bucket-1', + region: 'eu-west-1', + }, + 'https://s3.eu-west-1.amazonaws.com/bucket-1', + { + 'key1.yaml': 'generated-b390cd4de7ff00f6d51426870fc0e685029fbf09', + 'key2.yaml': 'generated-15ebeb1e53ffe71ea93f037076aefcdc5cc5e617', + 'key3.yaml': 'generated-fd0a33e70bafd707a60139decbd0383361ab3b4e', + 'key 4.yaml': 'generated-ac574fb266d9c8bd983b25a208c538e4ad2c1d06', + }, + { + s3ForcePathStyle: true, + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('apply full update on scheduled execution bucket with dot in it', async () => { + return expectMutation( + 'regionalStatic', + { + bucketName: 'bucket.1', + prefix: 'sub/dir/', + region: 'eu-west-1', + }, + 'https://s3.eu-west-1.amazonaws.com/bucket.1/sub/dir/', + { + 'key1.yaml': 'generated-651b5851d4670b7d5bb9a319d8f6eb295092e4ad', + 'key2.yaml': 'generated-ccddcdc3ad814aea072883118f3a9d0ac39a161e', + 'key3.yaml': 'generated-b2b8548903aa764544ab79dc81ab5093e6e4ba83', + 'key 4.yaml': 'generated-aafa9cc0422f5e8ccce1616dc0c74fa94f692af3', + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('us-east-1 does not have region-less URLs', async () => { return expectMutation( 'usEast1', { @@ -187,12 +271,12 @@ describe('AwsS3EntityProvider', () => { prefix: 'sub/dir/', region: 'us-east-1', }, - 'https://s3.amazonaws.com/bucket-1/sub/dir/', + 'https://bucket-1.s3.us-east-1.amazonaws.com/sub/dir/', { - 'key1.yaml': 'generated-f7e3f1c89f62cbf0d82db16452faaa7c040fc331', - 'key2.yaml': 'generated-925173f7dba1acaa73cac5ef4d10c3ed7660aa25', - 'key3.yaml': 'generated-d94cf017911ed7fb3be4a62a3dae1f5202879de3', - 'key 4.yaml': 'generated-f917fca0cfacc2be478ca2a3cff94d00917a1cde', + 'key1.yaml': 'generated-980e6ad47fbfbfeead708a9c7c87331b7540296a', + 'key2.yaml': 'generated-266794d8e789089dddba2b42cd79e70b149aa61c', + 'key3.yaml': 'generated-96f0cdcd7e33aa687c19d160ec7d5b1975cb9ea1', + 'key 4.yaml': 'generated-4f6d3ffb232e4a5b82c3a52549e4c36dab1c2f8d', }, ); }); @@ -209,18 +293,60 @@ describe('AwsS3EntityProvider', () => { bucketName: 'bucket-1', prefix: 'sub/dir/', }, - 'https://s3.eu-central-1.amazonaws.com/bucket-1/sub/dir/', + 'https://bucket-1.s3.eu-central-1.amazonaws.com/sub/dir/', { - 'key1.yaml': 'generated-285d144b5c1e24e801b97f61f794d566dabc7236', - 'key2.yaml': 'generated-36b78d7fa69690059797d4cc4f40c2a5eaed1d6d', - 'key3.yaml': 'generated-a39ad804bf65993cbc0f3810ff128a3c91daf768', - 'key 4.yaml': 'generated-bd7622ac86c313cb812d90e335b2f5f6bff14670', + 'key1.yaml': 'generated-bb17a9f9b420edd93137692f000b2d443a29239c', + 'key2.yaml': 'generated-b4559ecc8b615407e421dbaa3fcb9338e977b8ac', + 'key3.yaml': 'generated-bb3d500a6f8b351b0eed1aec77ebce65c1ab41fb', + 'key 4.yaml': 'generated-686de87f5882f6558b43280c5b6047e485199e88', }, ); }); // eslint-disable-next-line jest/expect-expect it('custom endpoint', async () => { + return expectMutation( + 'customEndpoint', + { + bucketName: 'bucket-1', + prefix: 'sub/dir/', + }, + 'http://bucket-1.localhost:1234/sub/dir/', + { + 'key1.yaml': 'generated-79625971ead9c39c91b0bfef4d7c748325e31234', + 'key2.yaml': 'generated-eeae95f16605d3afdc615436c18c9fbd35781299', + 'key3.yaml': 'generated-692976561563c3fa55889ad090363716c7b7e915', + 'key 4.yaml': 'generated-c8f92ea0eb96c355b7e56cbc461cef29f830747e', + }, + { + endpoint: 'http://localhost:1234/', + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('custom endpoint bucket dot', async () => { + return expectMutation( + 'customEndpoint', + { + bucketName: 'bucket.1', + prefix: 'sub/dir/', + }, + 'http://localhost:1234/bucket.1/sub/dir/', + { + 'key1.yaml': 'generated-07be77ac8626ac76a924414e0edf5ce66d3e0b27', + 'key2.yaml': 'generated-47295ada3c894cf9bac0d570a34d909244ea2f74', + 'key3.yaml': 'generated-30e98f3ebd350f3b618acd024199b5f31545495d', + 'key 4.yaml': 'generated-b71bc7661b92cef0db62c9652912fd5e4b245aa7', + }, + { + endpoint: 'http://localhost:1234/', + }, + ); + }); + + // eslint-disable-next-line jest/expect-expect + it('custom endpoint force path style', async () => { return expectMutation( 'customEndpoint', { @@ -235,7 +361,8 @@ describe('AwsS3EntityProvider', () => { 'key 4.yaml': 'generated-659f17a2429f107db04850f9081e3e9c56084aeb', }, { - endpoint: 'http://localhost:1234', + endpoint: 'http://localhost:1234/', + s3ForcePathStyle: true, }, ); }); @@ -305,12 +432,12 @@ describe('AwsS3EntityProvider', () => { }, }, }, - 'https://s3.eu-west-1.amazonaws.com/bucket-1/sub/dir/', + 'https://bucket-1.s3.eu-west-1.amazonaws.com/sub/dir/', { - 'key1.yaml': 'generated-7f6d5861b0b3401a38b5fe62e6c7ca11da5fd6d8', - 'key2.yaml': 'generated-a290be145586042af7d80715626399c9d661718d', - 'key3.yaml': 'generated-8d75f78ed9fa618ce433b226dc24eeab441f3a2d', - 'key 4.yaml': 'generated-1e0249dcb5805fc2ce6ac2d3c4d2a3ef4f1270c0', + 'key1.yaml': 'generated-8ece85ad90200c6577b99f553dcbedde05fa34bb', + 'key2.yaml': 'generated-6b54c6aaa44696f5e91ce0f54fb27bf837549d11', + 'key3.yaml': 'generated-88c703cf1aa66913db4033b029adc0b174574646', + 'key 4.yaml': 'generated-2b7e068bb4ec818c14f179a1e721843fc2dbc5f9', }, undefined, true, diff --git a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts index 8212f9279a..4a87a42e75 100644 --- a/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts +++ b/plugins/catalog-backend-module-aws/src/providers/AwsS3EntityProvider.ts @@ -23,13 +23,20 @@ import { locationSpecToLocationEntity, } from '@backstage/plugin-catalog-node'; import { LocationSpec } from '@backstage/plugin-catalog-common'; -import { AwsCredentials } from '../credentials/AwsCredentials'; import { readAwsS3Configs } from './config'; import { AwsS3Config } from './types'; -import { S3 } from 'aws-sdk'; -import { ListObjectsV2Output } from 'aws-sdk/clients/s3'; +import { + ListObjectsV2Command, + ListObjectsV2Output, + S3, +} from '@aws-sdk/client-s3'; import * as uuid from 'uuid'; import { Logger } from 'winston'; +import { getEndpointFromInstructions } from '@aws-sdk/middleware-endpoint'; +import { + AwsCredentialsManager, + DefaultAwsCredentialsManager, +} from '@backstage/integration-aws-node'; // TODO: event-based updates using S3 events (+ queue like SQS)? /** @@ -41,9 +48,10 @@ import { Logger } from 'winston'; */ export class AwsS3EntityProvider implements EntityProvider { private readonly logger: Logger; - private readonly s3: S3; + private s3?: S3; private readonly scheduleFn: () => Promise; private connection?: EntityProviderConnection; + private endpoint?: string; static fromConfig( configRoot: Config, @@ -78,7 +86,8 @@ export class AwsS3EntityProvider implements EntityProvider { `No schedule provided neither via code nor config for awsS3-provider:${providerConfig.id}.`, ); } - + const awsCredentialsManager = + DefaultAwsCredentialsManager.fromConfig(configRoot); const taskRunner = options.schedule ?? options.scheduler!.createScheduledTaskRunner(providerConfig.schedule!); @@ -86,6 +95,7 @@ export class AwsS3EntityProvider implements EntityProvider { return new AwsS3EntityProvider( providerConfig, integration, + awsCredentialsManager, options.logger, taskRunner, ); @@ -94,7 +104,8 @@ export class AwsS3EntityProvider implements EntityProvider { private constructor( private readonly config: AwsS3Config, - integration: AwsS3Integration, + private readonly integration: AwsS3Integration, + private readonly awsCredentialsManager: AwsCredentialsManager, logger: Logger, taskRunner: TaskRunner, ) { @@ -102,17 +113,6 @@ export class AwsS3EntityProvider implements EntityProvider { target: this.getProviderName(), }); - this.s3 = new S3({ - apiVersion: '2006-03-01', - credentials: AwsCredentials.create( - integration.config, - 'backstage-aws-s3-provider', - ), - endpoint: integration.config.endpoint, - region: this.config.region, - s3ForcePathStyle: integration.config.s3ForcePathStyle, - }); - this.scheduleFn = this.createScheduleFn(taskRunner); } @@ -146,6 +146,28 @@ export class AwsS3EntityProvider implements EntityProvider { /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */ async connect(connection: EntityProviderConnection): Promise { this.connection = connection; + const credProvider = + await this.awsCredentialsManager.getCredentialProvider(); + this.s3 = new S3({ + apiVersion: '2006-03-01', + credentialDefaultProvider: () => credProvider.sdkCredentialProvider, + endpoint: this.integration.config.endpoint, + region: this.config.region, + forcePathStyle: this.integration.config.s3ForcePathStyle, + }); + + // https://github.com/aws/aws-sdk-js-v3/issues/4122#issuecomment-1298968804 + const endpoint = await getEndpointFromInstructions( + { + Bucket: this.config.bucketName, + }, + ListObjectsV2Command, + this.s3.config as unknown as Record, + ); + if (endpoint?.url) + this.endpoint = endpoint.url.href.endsWith('/') + ? endpoint.url.href + : `${endpoint.url.href}/`; await this.scheduleFn(); } @@ -175,18 +197,21 @@ export class AwsS3EntityProvider implements EntityProvider { } private async listAllObjectKeys(): Promise { + if (!this.s3) { + throw new Error('Not initialized'); + } + const keys: string[] = []; let continuationToken: string | undefined = undefined; let output: ListObjectsV2Output; do { - const request = this.s3.listObjectsV2({ + output = await this.s3.listObjectsV2({ Bucket: this.config.bucketName, ContinuationToken: continuationToken, Prefix: this.config.prefix, }); - output = await request.promise(); if (output.Contents) { output.Contents.forEach(item => { if (item.Key && !item.Key.endsWith('/')) { @@ -209,9 +234,6 @@ export class AwsS3EntityProvider implements EntityProvider { } private createObjectUrl(key: string): string { - const bucketName = this.config.bucketName; - const endpoint = this.s3.endpoint.href; - - return encodeURI(`${endpoint}${bucketName}/${key}`); + return new URL(key, this.endpoint).href; } } diff --git a/plugins/catalog-backend-module-aws/src/types.ts b/plugins/catalog-backend-module-aws/src/types.ts index 3d9df38181..23460c104e 100644 --- a/plugins/catalog-backend-module-aws/src/types.ts +++ b/plugins/catalog-backend-module-aws/src/types.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Credentials } from 'aws-sdk'; +import { AwsCredentialIdentity } from '@aws-sdk/types'; /** * A factory for providing user-specified AWS credentials for a given AWS account. @@ -22,4 +22,4 @@ import { Credentials } from 'aws-sdk'; */ export type AWSCredentialFactory = ( awsAccountId: string, -) => Promise; +) => Promise; diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index e8458d82e7..21b95b5861 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 2e2ff96e7e..e9d6803571 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.16-next.1", + "version": "0.1.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index af6e6c3a7f..94c83e6b2e 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-bitbucket-cloud-common@0.2.6 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 77df5b12b4..00e4269342 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.12-next.1", + "version": "0.1.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 3c9e51b08e..ae894c2e12 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 68960fbf81..3dc8aca390 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.10-next.1", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index 0193d551a5..b7a9f2d0a2 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.6 + ## 0.2.12-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 64269a9102..1dbbb4bb45 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.12-next.1", + "version": "0.2.12", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index ea3d4af960..8f94db98f3 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.1.13-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 22bc3a95e5..a69aac5034 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.13-next.1", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index f54a55f9e9..427b48e7bb 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-catalog-backend-module-github +## 0.3.0 + +### Minor Changes + +- 970678adbe2: Implement events support for `GithubMultiOrgEntityProvider` + + **BREAKING:** Passing in a custom `teamTransformer` will now correctly completely override the default transformer behavior + +### Patch Changes + +- 78bb674a713: Fixed bug in queryWithPaging that caused secondary rate limit errors in GitHub with organizations having more than 1000 repositories. This change makes one request per second to avoid concurrency issues. +- bd101cefd37: Updated the `team.edited` event emitted from `GithubOrgEntityProvider` to also include teams description. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-events-node@0.2.6 + +## 0.3.0-next.2 + +### Minor Changes + +- 970678adbe2: Implement events support for `GithubMultiOrgEntityProvider` + + **BREAKING:** Passing in a custom `teamTransformer` will now correctly completely override the default transformer behavior + +### Patch Changes + +- bd101cefd37: Updated the `team.edited` event emitted from `GithubOrgEntityProvider` to also include teams description. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index 0698fae8a0..7b944b33a9 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -10,6 +10,7 @@ import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; +import { EventBroker } from '@backstage/plugin-events-node'; import { EventParams } from '@backstage/plugin-events-node'; import { EventSubscriber } from '@backstage/plugin-events-node'; import { GithubCredentialsProvider } from '@backstage/integration'; @@ -158,6 +159,7 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { // @public export interface GithubMultiOrgEntityProviderOptions { + eventBroker?: EventBroker; githubCredentialsProvider?: GithubCredentialsProvider; githubUrl: string; id: string; diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 5b29baa05c..029acdf0e0 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.2.8-next.1", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index df4565a174..7a0a29e098 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -21,6 +21,7 @@ import { graphql as graphqlMsw } from 'msw'; import { setupServer } from 'msw/node'; import { TeamTransformer, UserTransformer } from './defaultTransformers'; import { + getOrganizationsFromUser, getOrganizationTeams, getOrganizationUsers, getTeamMembers, @@ -448,6 +449,37 @@ describe('github', () => { }); }); + describe('getOrganizationsFromUser', () => { + it('reads orgs from user', async () => { + const input: QueryResponse = { + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'a', + }, + { + login: 'b', + }, + { + login: 'c', + }, + ], + }, + }, + }; + + server.use( + graphqlMsw.query('orgs', (_req, res, ctx) => res(ctx.data(input))), + ); + + await expect(getOrganizationsFromUser(graphql, 'foo')).resolves.toEqual({ + orgs: ['a', 'b', 'c'], + }); + }); + }); + describe('getTeamMembers', () => { it('reads team members', async () => { const input: QueryResponse = { diff --git a/plugins/catalog-backend-module-github/src/lib/github.ts b/plugins/catalog-backend-module-github/src/lib/github.ts index d0b629092a..412b751c38 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.ts @@ -33,6 +33,7 @@ import { DeferredEntity } from '@backstage/plugin-catalog-node'; export type QueryResponse = { organization?: OrganizationResponse; repositoryOwner?: RepositoryOwnerResponse; + user?: UserResponse; }; type RepositoryOwnerResponse = { @@ -46,11 +47,19 @@ export type OrganizationResponse = { repositories?: Connection; }; +export type UserResponse = { + organizations?: Connection; +}; + export type PageInfo = { hasNextPage: boolean; endCursor?: string; }; +export type GithubOrg = { + login: string; +}; + /** * Github User * @@ -334,6 +343,34 @@ export async function getOrganizationTeamsFromUsers( return { groups }; } +export async function getOrganizationsFromUser( + client: typeof graphql, + user: string, +): Promise<{ + orgs: string[]; +}> { + const query = ` + query orgs($user: String!) { + user(login: $user) { + organizations(first: 100) { + nodes { login } + pageInfo { hasNextPage, endCursor } + } + } + }`; + + const orgs = await queryWithPaging( + client, + query, + '', + r => r.user?.organizations, + async o => o.login, + { user }, + ); + + return { orgs }; +} + export async function getOrganizationTeam( client: typeof graphql, org: string, diff --git a/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.test.ts index 76ab55552d..99bef6e074 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.test.ts @@ -16,11 +16,13 @@ import { getVoidLogger } from '@backstage/backend-common'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; +import { ConfigReader } from '@backstage/config'; import { GithubCredentialsProvider, GithubIntegrationConfig, } from '@backstage/integration'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; import { graphql } from '@octokit/graphql'; import { GithubMultiOrgEntityProvider, @@ -160,7 +162,7 @@ describe('GithubMultiOrgEntityProvider', () => { const logger = getVoidLogger(); const gitHubConfig: GithubIntegrationConfig = { - host: 'https://github.com', + host: 'github.com', }; const mockGetCredentials = jest.fn().mockReturnValue({ @@ -201,9 +203,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/a', + 'url:https://github.com/a', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/a', + 'url:https://github.com/a', 'github.com/user-login': 'a', }, description: 'c', @@ -227,9 +229,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/x', + 'url:https://github.com/x', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/x', + 'url:https://github.com/x', 'github.com/user-login': 'x', }, description: 'z', @@ -253,9 +255,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/q', + 'url:https://github.com/q', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/q', + 'url:https://github.com/q', 'github.com/user-login': 'q', }, description: 's', @@ -279,9 +281,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/orgs/orgA/teams/team', + 'url:https://github.com/orgs/orgA/teams/team', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/orgs/orgA/teams/team', + 'url:https://github.com/orgs/orgA/teams/team', 'github.com/team-slug': 'orgA/team', }, namespace: 'orga', @@ -308,9 +310,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/orgs/orgB/teams/team', + 'url:https://github.com/orgs/orgB/teams/team', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/orgs/orgB/teams/team', + 'url:https://github.com/orgs/orgB/teams/team', 'github.com/team-slug': 'orgB/team', }, namespace: 'orgb', @@ -467,7 +469,7 @@ describe('GithubMultiOrgEntityProvider', () => { const logger = getVoidLogger(); const gitHubConfig: GithubIntegrationConfig = { - host: 'https://github.com', + host: 'github.com', }; const mockGetCredentials = jest.fn().mockReturnValue({ @@ -507,9 +509,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/a', + 'url:https://github.com/a', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/a', + 'url:https://github.com/a', 'github.com/user-login': 'a', }, description: 'c', @@ -533,9 +535,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/x', + 'url:https://github.com/x', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/x', + 'url:https://github.com/x', 'github.com/user-login': 'x', }, description: 'z', @@ -559,9 +561,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/q', + 'url:https://github.com/q', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/q', + 'url:https://github.com/q', 'github.com/user-login': 'q', }, description: 's', @@ -585,9 +587,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/orgs/orgC/teams/team', + 'url:https://github.com/orgs/orgC/teams/team', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/orgs/orgC/teams/team', + 'url:https://github.com/orgs/orgC/teams/team', 'github.com/team-slug': 'orgC/team', }, namespace: 'orgc', @@ -614,9 +616,9 @@ describe('GithubMultiOrgEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:https://https://github.com/orgs/orgD/teams/team', + 'url:https://github.com/orgs/orgD/teams/team', 'backstage.io/managed-by-origin-location': - 'url:https://https://github.com/orgs/orgD/teams/team', + 'url:https://github.com/orgs/orgD/teams/team', 'github.com/team-slug': 'orgD/team', }, namespace: 'orgd', @@ -713,4 +715,1223 @@ describe('GithubMultiOrgEntityProvider', () => { }); }); }); + + describe('events', () => { + let onEvent: Function; + + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + + beforeEach(() => { + const logger = getVoidLogger(); + const config = new ConfigReader({ + integrations: { + github: [ + { + host: 'github.com', + }, + ], + }, + }); + + const mockGetCredentials = jest.fn().mockReturnValue({ + headers: { token: 'blah' }, + type: 'app', + }); + + const githubCredentialsProvider: GithubCredentialsProvider = { + getCredentials: mockGetCredentials, + }; + + const mockEventBroker = { + publish: async () => {}, + subscribe: (subscriber: EventSubscriber) => { + onEvent = subscriber.onEvent; + }, + }; + + const entityProvider = GithubMultiOrgEntityProvider.fromConfig(config, { + id: 'my-id', + githubCredentialsProvider, + githubUrl: 'https://github.com', + logger, + orgs: ['orgA', 'orgB'], + eventBroker: mockEventBroker, + }); + + entityProvider.connect(entityProviderConnection); + }); + + afterEach(() => jest.resetAllMocks()); + + it('should ignore events from non-applicable orgs', async () => { + await onEvent({ + topic: 'github.organization', + eventPayload: { + action: 'member_added', + membership: { + user: { + name: 'githubuser', + login: 'githubuser', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + }, + }, + organization: { + login: 'test-org', + }, + }, + }); + + expect(entityProviderConnection.applyMutation).not.toHaveBeenCalled(); + + await onEvent({ + topic: 'github.installation', + eventPayload: { + action: 'created', + installation: { + account: { + login: 'test-org', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).not.toHaveBeenCalled(); + }); + + describe('installation', () => { + it('adds users and groups from new org', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + organization: { + membersWithRole: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'a', + name: 'b', + bio: 'c', + email: 'd', + avatarUrl: 'e', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgB/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: { pageInfo: { hasNextPage: false }, nodes: [] }, + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a' }], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: { pageInfo: { hasNextPage: false }, nodes: [] }, + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a' }], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgB/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + parentTeam: { + slug: 'parent', + combinedSlug: '', + members: { pageInfo: { hasNextPage: false }, nodes: [] }, + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a' }], + }, + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.installation', + eventPayload: { + action: 'created', + installation: { + account: { + login: 'orgB', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + description: 'c', + name: 'a', + }, + spec: { + memberOf: ['orga/team', 'orgb/team'], + profile: { + displayName: 'b', + email: 'd', + picture: 'e', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgB/teams/team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgB/teams/team', + 'github.com/team-slug': 'orgB/team', + }, + namespace: 'orgb', + name: 'team', + description: 'The one and only team', + }, + spec: { + children: [], + parent: 'parent', + profile: { + displayName: 'TeamB', + picture: 'http://example.com/team.jpeg', + }, + type: 'team', + members: ['default/a'], + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + }); + + describe('organization', () => { + it('should add a new user', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'orgA', + }, + { + login: 'orgB', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.organization', + eventPayload: { + action: 'member_added', + organization: { + login: 'orgB', + }, + membership: { + user: { + name: 'a', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + login: 'a', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + }, + spec: { + memberOf: ['orga/team'], + profile: { + displayName: 'a', + email: 'user1@test.com', + picture: 'https://avatars.githubusercontent.com/u/83820368', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + + it('should remove a user', async () => { + const mockClient = jest.fn(); + + mockClient.mockResolvedValueOnce({ + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'orgC', + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.organization', + eventPayload: { + action: 'member_removed', + organization: { + login: 'orgB', + }, + membership: { + user: { + name: 'a', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + login: 'a', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + }, + spec: { + memberOf: [], + profile: { + displayName: 'a', + email: 'user1@test.com', + picture: 'https://avatars.githubusercontent.com/u/83820368', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + }); + }); + + it('should only update group memberships of a user that still belongs to an applicable org', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'orgA', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.organization', + eventPayload: { + action: 'member_removed', + organization: { + login: 'orgB', + }, + membership: { + user: { + name: 'a', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + login: 'a', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + }, + spec: { + memberOf: ['orga/team'], + profile: { + displayName: 'a', + email: 'user1@test.com', + picture: 'https://avatars.githubusercontent.com/u/83820368', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + }); + + describe('team', () => { + it('should create a new group from a new team', async () => { + await onEvent({ + topic: 'github.team', + eventPayload: { + action: 'created', + organization: { + login: 'orgB', + }, + team: { + name: 'New Team', + slug: 'new-team', + description: 'description from the new team', + html_url: 'https://github.com/orgs/orgB/teams/new-team', + parent: { + slug: 'father-team', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'new-team', + namespace: 'orgb', + description: 'description from the new team', + annotations: { + 'backstage.io/edit-url': + 'https://github.com/orgs/orgB/teams/new-team/edit', + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgB/teams/new-team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgB/teams/new-team', + 'github.com/team-slug': 'orgB/new-team', + }, + }, + spec: { + type: 'team', + children: [], + members: [], + parent: 'father-team', + profile: { + displayName: 'New Team', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + + it('should remove a group from a deleted team', async () => { + await onEvent({ + topic: 'github.team', + eventPayload: { + action: 'deleted', + organization: { + login: 'orgB', + }, + team: { + name: 'New Team', + slug: 'new-team', + description: 'description from the new team', + html_url: 'https://github.com/orgs/orgB/teams/new-team', + parent: { + slug: 'father-team', + }, + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [], + removed: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + name: 'new-team', + namespace: 'orgb', + description: 'description from the new team', + annotations: { + 'backstage.io/edit-url': + 'https://github.com/orgs/orgB/teams/new-team/edit', + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgB/teams/new-team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgB/teams/new-team', + 'github.com/team-slug': 'orgB/new-team', + }, + }, + spec: { + type: 'team', + children: [], + members: [], + parent: 'father-team', + profile: { + displayName: 'New Team', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + }); + }); + + it('should update group and user entities when a team is edited', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + organization: { + team: { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + membersWithRole: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'a', + name: 'b', + bio: 'c', + email: 'd', + avatarUrl: 'e', + }, + { + login: 'w', + name: 'x', + bio: 'y', + email: 'z', + avatarUrl: 'q', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgB/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.team', + eventPayload: { + action: 'edited', + changes: { + name: { + from: 'oldName', + }, + description: { + from: 'oldDescription', + }, + }, + team: { + slug: 'team', + parent: { + slug: 'parent', + }, + }, + organization: { + login: 'orgA', + }, + }, + }); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + description: 'c', + }, + spec: { + memberOf: ['orga/team', 'orgb/team'], + profile: { + displayName: 'b', + email: 'd', + picture: 'e', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/edit-url': 'https://example.com', + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'github.com/team-slug': 'orgA/team', + }, + namespace: 'orga', + name: 'team', + description: 'The one and only team', + }, + spec: { + children: [], + parent: 'parent', + profile: { + displayName: 'TeamA', + picture: 'http://example.com/team.jpeg', + }, + type: 'team', + members: ['default/a'], + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgA/teams/oldname', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgA/teams/oldname', + 'github.com/team-slug': 'orgA/oldname', + }, + namespace: 'orga', + name: 'oldname', + description: 'oldDescription', + }, + spec: { + children: [], + parent: 'parent', + profile: { + displayName: 'oldName', + }, + type: 'team', + members: [], + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + }); + }); + }); + + describe('membership', () => { + it('should update group and user entities when a member is added', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + organization: { + team: { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + }, + }) + .mockResolvedValueOnce({ + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'orgA', + }, + { + login: 'orgB', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgB/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.membership', + eventPayload: { + action: 'added', + organization: { + login: 'orgA', + }, + team: { + slug: 'teama', + }, + member: { + name: 'a', + login: 'a', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + }, + }, + }); + await new Promise(process.nextTick); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + }, + spec: { + memberOf: ['orga/team', 'orgb/team'], + profile: { + displayName: 'a', + email: 'user1@test.com', + picture: 'https://avatars.githubusercontent.com/u/83820368', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/edit-url': 'https://example.com', + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'github.com/team-slug': 'orgA/team', + }, + namespace: 'orga', + name: 'team', + description: 'The one and only team', + }, + spec: { + children: [], + parent: 'parent', + profile: { + displayName: 'TeamA', + picture: 'http://example.com/team.jpeg', + }, + type: 'team', + members: ['default/a'], + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + + it('should update group and user entities when a member is removed', async () => { + const mockClient = jest.fn(); + + mockClient + .mockResolvedValueOnce({ + organization: { + team: { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [], + }, + }, + }, + }) + .mockResolvedValueOnce({ + user: { + organizations: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + login: 'orgA', + }, + { + login: 'orgB', + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgA/team', + name: 'TeamA', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [], + }, + }, + ], + }, + }, + }) + .mockResolvedValueOnce({ + organization: { + teams: { + pageInfo: { hasNextPage: false }, + nodes: [ + { + slug: 'team', + combinedSlug: 'orgB/team', + name: 'TeamB', + description: 'The one and only team', + avatarUrl: 'http://example.com/team.jpeg', + editTeamUrl: 'https://example.com', + parentTeam: { + slug: 'parent', + }, + members: { + pageInfo: { hasNextPage: false }, + nodes: [{ login: 'a', name: 'a' }], + }, + }, + ], + }, + }, + }); + + (graphql.defaults as jest.Mock).mockReturnValue(mockClient); + + await onEvent({ + topic: 'github.membership', + eventPayload: { + action: 'removed', + organization: { + login: 'orgA', + }, + team: { + slug: 'teama', + }, + member: { + name: 'a', + login: 'a', + avatar_url: 'https://avatars.githubusercontent.com/u/83820368', + email: 'user1@test.com', + }, + }, + }); + await new Promise(process.nextTick); + + expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1); + expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({ + type: 'delta', + added: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://github.com/a', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/a', + 'github.com/user-login': 'a', + }, + name: 'a', + }, + spec: { + memberOf: ['orgb/team'], + profile: { + displayName: 'a', + email: 'user1@test.com', + picture: 'https://avatars.githubusercontent.com/u/83820368', + }, + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/edit-url': 'https://example.com', + 'backstage.io/managed-by-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'backstage.io/managed-by-origin-location': + 'url:https://github.com/orgs/orgA/teams/team', + 'github.com/team-slug': 'orgA/team', + }, + namespace: 'orga', + name: 'team', + description: 'The one and only team', + }, + spec: { + children: [], + parent: 'parent', + profile: { + displayName: 'TeamA', + picture: 'http://example.com/team.jpeg', + }, + type: 'team', + members: [], + }, + }, + locationKey: 'github-multi-org-provider:my-id', + }, + ], + removed: [], + }); + }); + }); + }); }); diff --git a/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.ts index ce45f30d96..51796c2116 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubMultiOrgEntityProvider.ts @@ -21,7 +21,9 @@ import { DEFAULT_NAMESPACE, Entity, GroupEntity, + parseEntityRef, stringifyEntityRef, + UserEntity, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { @@ -32,10 +34,24 @@ import { ScmIntegrations, } from '@backstage/integration'; import { + DeferredEntity, EntityProvider, EntityProviderConnection, } from '@backstage/plugin-catalog-node'; +import { EventBroker, EventParams } from '@backstage/plugin-events-node'; import { graphql } from '@octokit/graphql'; +import { + InstallationCreatedEvent, + InstallationEvent, + OrganizationEvent, + OrganizationMemberAddedEvent, + OrganizationMemberRemovedEvent, + MembershipEvent, + TeamCreatedEvent, + TeamDeletedEvent, + TeamEditedEvent, + TeamEvent, +} from '@octokit/webhooks-types'; import { merge } from 'lodash'; import * as uuid from 'uuid'; import { Logger } from 'winston'; @@ -44,6 +60,7 @@ import { assignGroupsToUsers, buildOrgHierarchy, defaultOrganizationTeamTransformer, + defaultUserTransformer, getOrganizationTeams, getOrganizationUsers, GithubTeam, @@ -55,6 +72,11 @@ import { ANNOTATION_GITHUB_TEAM_SLUG, ANNOTATION_GITHUB_USER_LOGIN, } from '../lib/annotation'; +import { + getOrganizationsFromUser, + getOrganizationTeam, + getOrganizationTeamsFromUsers, +} from '../lib/github'; import { splitTeamSlug } from '../lib/util'; /** @@ -118,8 +140,18 @@ export interface GithubMultiOrgEntityProviderOptions { * By default groups will be namespaced according to their GitHub org. */ teamTransformer?: TeamTransformer; + + /** + * An EventBroker to subscribe this provider to GitHub events to trigger delta mutations + */ + eventBroker?: EventBroker; } +type CreateDeltaOperation = (entities: Entity[]) => { + added: DeferredEntity[]; + removed: DeferredEntity[]; +}; + /** * Ingests org data (users and groups) from GitHub. * @@ -161,6 +193,13 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { provider.schedule(options.schedule); + if (options.eventBroker) { + options.eventBroker.subscribe({ + supportsEventTopics: provider.supportsEventTopics.bind(provider), + onEvent: provider.onEvent.bind(provider), + }); + } + return provider; } @@ -271,6 +310,476 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { markCommitComplete(); } + private supportsEventTopics(): string[] { + return [ + 'github.installation', + 'github.organization', + 'github.team', + 'github.membership', + ]; + } + + private async onEvent(params: EventParams): Promise { + const { logger } = this.options; + logger.debug(`Received event from ${params.topic}`); + + const orgs = this.options.orgs?.length + ? this.options.orgs + : await this.getAllOrgs(this.options.gitHubConfig); + + const eventPayload = params.eventPayload as + | InstallationEvent + | OrganizationEvent + | MembershipEvent + | TeamEvent; + + if ( + !orgs.includes( + (eventPayload as InstallationEvent).installation?.account?.login, + ) && + !orgs.includes( + (eventPayload as OrganizationEvent | MembershipEvent | TeamEvent) + .organization?.login, + ) + ) { + return; + } + + // https://docs.github.com/webhooks-and-events/webhooks/webhook-events-and-payloads#installation + if ( + params.topic.includes('installation') && + eventPayload.action === 'created' + ) { + // We can only respond to installation.created events to add new users/groups since a + // installation.deleted event won't provide us info on what user/groups we should remove and + // we can't query the uninstalled org since we will no longer have access. This will need to be + // eventually resolved via occasional full mutation runs by calling read() + await this.onInstallationChange( + eventPayload as InstallationCreatedEvent, + orgs, + ); + } + + // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#organization + if ( + params.topic.includes('organization') && + (eventPayload.action === 'member_added' || + eventPayload.action === 'member_removed') + ) { + await this.onMemberChangeInOrganization(eventPayload, orgs); + } + + // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#team + if (params.topic.includes('team')) { + if ( + eventPayload.action === 'created' || + eventPayload.action === 'deleted' + ) { + await this.onTeamChangeInOrganization( + eventPayload as TeamCreatedEvent | TeamDeletedEvent, + ); + } else if (eventPayload.action === 'edited') { + await this.onTeamEditedInOrganization( + eventPayload as TeamEditedEvent, + orgs, + ); + } + } + + // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#membership + if (params.topic.includes('membership')) { + this.onMembershipChangedInTeam(eventPayload as MembershipEvent, orgs); + } + + return; + } + + private async onInstallationChange( + event: InstallationCreatedEvent, + applicableOrgs: string[], + ) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + const org = event.installation.account.login; + const { headers, type: tokenType } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${org}`, + }); + const client = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers, + }); + + const { users } = await getOrganizationUsers( + client, + org, + tokenType, + this.options.userTransformer, + ); + + const { groups } = await getOrganizationTeams( + client, + org, + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + // Fetch group memberships of users in case they already exist and + // have memberships in groups from other applicable orgs + for (const userOrg of applicableOrgs) { + const { headers: orgHeaders } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${userOrg}`, + }); + const orgClient = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers: orgHeaders, + }); + + const { groups: userGroups } = await getOrganizationTeamsFromUsers( + orgClient, + userOrg, + users.map( + u => + u.metadata.annotations?.[ANNOTATION_GITHUB_USER_LOGIN] || + u.metadata.name, + ), + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + assignGroupsToUsers(users, userGroups); + } + + const { added, removed } = this.createAddEntitiesOperation([ + ...users, + ...groups, + ]); + await this.connection.applyMutation({ + type: 'delta', + removed, + added, + }); + } + + private async onMemberChangeInOrganization( + event: OrganizationMemberAddedEvent | OrganizationMemberRemovedEvent, + applicableOrgs: string[], + ) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + const userTransformer = + this.options.userTransformer || defaultUserTransformer; + const { name, avatar_url: avatarUrl, email, login } = event.membership.user; + const org = event.organization.login; + const { headers } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${org}`, + }); + const client = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers, + }); + + const { orgs } = await getOrganizationsFromUser(client, login); + const userApplicableOrgs = orgs.filter(o => applicableOrgs.includes(o)); + + let updateMemberships: boolean; + let createDeltaOperation: CreateDeltaOperation; + if (event.action === 'member_removed') { + if (userApplicableOrgs.length) { + // If the user is still associated with another applicable org then we don't want to remove + // them, just update the entity to remove any potential group memberships from the old org + createDeltaOperation = this.createAddEntitiesOperation.bind(this); + updateMemberships = true; + } else { + // User is no longer part of any applicable orgs so we can remove it, + // no need to take memberships into account + createDeltaOperation = this.createRemoveEntitiesOperation.bind(this); + updateMemberships = false; + } + } else { + // We're not sure if this user was already added as part of another applicable org + // so grab the latest memberships (potentially from teams of other orgs) to ensure + // we're not accidentally omitting them + createDeltaOperation = this.createAddEntitiesOperation.bind(this); + updateMemberships = true; + } + + const user = (await userTransformer( + { + name, + avatarUrl, + login, + email: email ?? undefined, + }, + { + org, + client, + query: '', + }, + )) as UserEntity; + + if (updateMemberships) { + for (const userOrg of userApplicableOrgs) { + const { headers: orgHeaders } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${userOrg}`, + }); + const orgClient = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers: orgHeaders, + }); + + const { groups } = await getOrganizationTeamsFromUsers( + orgClient, + userOrg, + [login], + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + assignGroupsToUsers([user], groups); + } + } + + const { added, removed } = createDeltaOperation([user]); + await this.connection.applyMutation({ + type: 'delta', + removed, + added, + }); + } + + private async onTeamChangeInOrganization( + event: TeamCreatedEvent | TeamDeletedEvent, + ) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + const org = event.organization.login; + const { headers } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${org}`, + }); + const client = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers, + }); + + const { name, html_url: url, description, slug } = event.team; + const group = (await this.defaultMultiOrgTeamTransformer( + { + name, + slug, + editTeamUrl: `${url}/edit`, + combinedSlug: `${org}/${slug}`, + description: description ?? undefined, + parentTeam: { slug: event.team?.parent?.slug || '' } as GithubTeam, + // entity will be removed or is new + members: [], + }, + { + org, + client, + query: '', + }, + )) as Entity; + + const createDeltaOperation = + event.action === 'created' + ? this.createAddEntitiesOperation.bind(this) + : this.createRemoveEntitiesOperation.bind(this); + const { added, removed } = createDeltaOperation([group]); + + await this.connection.applyMutation({ + type: 'delta', + removed, + added, + }); + } + + private async onTeamEditedInOrganization( + event: TeamEditedEvent, + applicableOrgs: string[], + ) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + const org = event.organization.login; + const { headers, type: tokenType } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${org}`, + }); + const client = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers, + }); + + const teamSlug = event.team.slug; + const { group } = await getOrganizationTeam( + client, + org, + teamSlug, + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + const { users } = await getOrganizationUsers( + client, + org, + tokenType, + this.options.userTransformer, + ); + + const usersFromChangedGroup = + group.spec.members?.map(m => + stringifyEntityRef(parseEntityRef(m, { defaultKind: 'user' })), + ) || []; + const usersToRebuild = users.filter(u => + usersFromChangedGroup.includes(stringifyEntityRef(u)), + ); + + // Update memberships of associated members of this group in case the group entity ref changed + for (const userOrg of applicableOrgs) { + const { headers: orgHeaders } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${userOrg}`, + }); + const orgClient = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers: orgHeaders, + }); + + const { groups } = await getOrganizationTeamsFromUsers( + orgClient, + userOrg, + usersToRebuild.map( + u => + u.metadata.annotations?.[ANNOTATION_GITHUB_USER_LOGIN] || + u.metadata.name, + ), + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + assignGroupsToUsers(usersToRebuild, groups); + } + + const oldName = event.changes.name?.from || ''; + const oldSlug = oldName.toLowerCase().replaceAll(/\s/gi, '-'); + const oldGroup = (await this.defaultMultiOrgTeamTransformer( + { + name: event.changes.name?.from, + slug: oldSlug, + combinedSlug: `${org}/${oldSlug}`, + description: event.changes.description?.from, + parentTeam: { slug: event.team?.parent?.slug || '' } as GithubTeam, + // entity will be removed + members: [], + }, + { + org, + client, + query: '', + }, + )) as Entity; + + // Remove the old group entity in case the entity ref is now different + const { removed } = this.createRemoveEntitiesOperation([oldGroup]); + const { added } = this.createAddEntitiesOperation([ + ...usersToRebuild, + group, + ]); + await this.connection.applyMutation({ + type: 'delta', + removed, + added, + }); + } + + private async onMembershipChangedInTeam( + event: MembershipEvent, + applicableOrgs: string[], + ) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + // The docs are saying I will receive the slug for the removed event, + // but the types don't reflect that, + // so I will just check to be sure the slug is there + // https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#membership + if (!('slug' in event.team)) { + return; + } + + const org = event.organization.login; + const { headers } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${org}`, + }); + const client = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers, + }); + + const teamSlug = event.team.slug; + const { group } = await getOrganizationTeam( + client, + org, + teamSlug, + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + const userTransformer = + this.options.userTransformer || defaultUserTransformer; + const { name, avatar_url: avatarUrl, email, login } = event.member; + const user = (await userTransformer( + { + name, + avatarUrl, + login, + email: email ?? undefined, + }, + { + org, + client, + query: '', + }, + )) as UserEntity; + + const { orgs } = await getOrganizationsFromUser(client, login); + const userApplicableOrgs = orgs.filter(o => applicableOrgs.includes(o)); + for (const userOrg of userApplicableOrgs) { + const { headers: orgHeaders } = + await this.options.githubCredentialsProvider.getCredentials({ + url: `${this.options.githubUrl}/${userOrg}`, + }); + const orgClient = graphql.defaults({ + baseUrl: this.options.gitHubConfig.apiBaseUrl, + headers: orgHeaders, + }); + + const { groups } = await getOrganizationTeamsFromUsers( + orgClient, + userOrg, + [login], + this.defaultMultiOrgTeamTransformer.bind(this), + ); + + assignGroupsToUsers([user], groups); + } + + const { added, removed } = this.createAddEntitiesOperation([user, group]); + await this.connection.applyMutation({ + type: 'delta', + removed, + added, + }); + } + private schedule(schedule: GithubMultiOrgEntityProviderOptions['schedule']) { if (!schedule || schedule === 'manual') { return; @@ -301,9 +810,11 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { team: GithubTeam, ctx: TransformerContext, ): Promise { - const result = this.options.teamTransformer - ? await this.options.teamTransformer(team, ctx) - : await defaultOrganizationTeamTransformer(team, ctx); + if (this.options.teamTransformer) { + return await this.options.teamTransformer(team, ctx); + } + + const result = await defaultOrganizationTeamTransformer(team, ctx); if (result) { result.metadata.namespace = ctx.org.toLocaleLowerCase('en-US'); @@ -333,6 +844,32 @@ export class GithubMultiOrgEntityProvider implements EntityProvider { ) .filter(Boolean) as string[]; } + + private createAddEntitiesOperation(entities: Entity[]) { + return { + removed: [], + added: entities.map(entity => ({ + locationKey: `github-multi-org-provider:${this.options.id}`, + entity: withLocations( + `https://${this.options.gitHubConfig.host}`, + entity, + ), + })), + }; + } + + private createRemoveEntitiesOperation(entities: Entity[]) { + return { + added: [], + removed: entities.map(entity => ({ + locationKey: `github-multi-org-provider:${this.options.id}`, + entity: withLocations( + `https://${this.options.gitHubConfig.host}`, + entity, + ), + })), + }; + } } // Helps wrap the timing and logging behaviors diff --git a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts index ff42e42718..3e58c1473f 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.test.ts @@ -833,6 +833,7 @@ describe('GithubOrgEntityProvider', () => { 'url:https://github.com/orgs/backstage/teams/mygroup-with-spaces', }, name: 'mygroup-with-spaces', + description: 'description-from-the-new-team', }, apiVersion: 'backstage.io/v1alpha1', kind: 'Group', diff --git a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts index 02e225c938..c181510a67 100644 --- a/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GithubOrgEntityProvider.ts @@ -371,14 +371,21 @@ export class GithubOrgEntityProvider assignGroupsToUsers(usersToRebuild, groups); buildOrgHierarchy(groups); - const oldName = event.changes.name?.from || ''; + const oldName = event.changes.name?.from || event.team.name; const oldSlug = oldName.toLowerCase().replaceAll(/\s/gi, '-'); + const oldDescription = + event.changes.description?.from || event.team.description; + const oldDescriptionSlug = oldDescription + ?.toLowerCase() + .replaceAll(/\s/gi, '-'); + const { removed } = createDeltaOperation(org, [ { ...group, metadata: { name: oldSlug, + description: oldDescriptionSlug, }, }, ]); diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 9882178a2b..a8c58d386a 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.2.1 + +### Patch Changes + +- b12c41fafc4: Fix a corner case where returned users are null for bots +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 22237862aa..223d578da1 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.2.1-next.1", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index 8f8c67895c..46932c95c6 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -128,10 +128,11 @@ export class GitLabClient { throw new Error(`GraphQL errors: ${JSON.stringify(response.errors)}`); } memberIds.push( - ...response.data.group.groupMembers.nodes.map( - (node: { user: { id: string } }) => + ...response.data.group.groupMembers.nodes + .filter(n => n.user) + .map(node => Number(node.user.id.replace(/^gid:\/\/gitlab\/User\//, '')), - ), + ), ); ({ hasNextPage, endCursor } = response.data.group.groupMembers.pageInfo); } while (hasNextPage); diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 9921b0dabc..fdf0de5b0b 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-events-node@0.2.6 + - @backstage/plugin-permission-common@0.7.5 + +## 0.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 686c89cd25..b37f2bfb6c 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", "description": "An entity provider for streaming large asset sources into the catalog", - "version": "0.3.2-next.1", + "version": "0.3.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 104e3f1c0f..052f1cc473 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + ## 0.5.12-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 120131d95a..6943df23fe 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.12-next.1", + "version": "0.5.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index c0c0888f38..f45e0c3440 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + ## 0.5.4-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 026386457a..ae836681b4 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.5.4-next.1", + "version": "0.5.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 5fc587a4f9..0598ea46ef 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.11 + +### Patch Changes + +- accaceadffa: Fixed bug in `jsonSchemaRefPlaceholderResolver` where relative $ref files were resolved through file system instead of base URL of file +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + +## 0.1.11-next.2 + +### Patch Changes + +- accaceadffa: Fixed bug in `jsonSchemaRefPlaceholderResolver` where relative $ref files were resolved through file system instead of base URL of file +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/config@1.0.7 + ## 0.1.11-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index e02490ef59..980a8920cd 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.11-next.1", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index 39bd1e3cdc..e8750bc1c4 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.1.2 + +### Patch Changes + +- 95b2168d71b: Fixes import paths and updates documentation +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.1.2-next.2 + +### Patch Changes + +- 95b2168d71b: Fixes import paths and updates documentation +- Updated dependencies + - @backstage/config@1.0.7 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 65bda327dd..7286f66095 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", - "version": "0.1.2-next.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 1a715e26bc..e8c18be461 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-catalog-backend +## 1.9.1 + +### Patch Changes + +- ce8d203235b: Ensure that entity cache state is only written to the database when actually changed +- 485a6c5f7b5: Internal refactoring for performance in the service handlers +- 3587a968dcd: Fixed a bug in the `queryEntities` endpoint that was causing filtered entities to be included in cursor requests. +- ce335df9d1c: Improve the query for orphan pruning +- 27956d78671: Adjusted the OpenAPI schema file name according to the new structure +- 51064e6e5ee: Change orphan cleanup task to only log a message if it deleted entities. +- 12a345317ab: Remove unnecessary join in the entity facets endpoint, exclude nulls +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/plugin-search-backend-module-catalog@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.9.1-next.2 + +### Patch Changes + +- ce8d203235b: Ensure that entity cache state is only written to the database when actually changed +- 485a6c5f7b5: Internal refactoring for performance in the service handlers +- 3587a968dcd: Fixed a bug in the `queryEntities` endpoint that was causing filtered entities to be included in cursor requests. +- 12a345317ab: Remove unnecessary join in the entity facets endpoint, exclude nulls +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/config@1.0.7 + ## 1.9.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 289a9a801d..1a2ca55253 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.9.1-next.1", + "version": "1.9.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts index 920acae7bd..eeab85f59e 100644 --- a/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts +++ b/plugins/catalog-backend/src/database/operations/util/deleteOrphanedEntities.ts @@ -33,13 +33,16 @@ export async function deleteOrphanedEntities(options: { // Limit iterations for sanity for (let i = 0; i < 100; ++i) { const candidates = await tx - .with('orphans', orphans => + .with('orphans', ['entity_id', 'entity_ref'], orphans => orphans - .from('refresh_state') - .select('entity_id', 'entity_ref') - .whereNotIn('entity_ref', keep => - keep.distinct('target_entity_ref').from('refresh_state_references'), - ), + .from('refresh_state') + .select('refresh_state.entity_id', 'refresh_state.entity_ref') + .leftOuterJoin( + 'refresh_state_references', + 'refresh_state_references.target_entity_ref', + 'refresh_state.entity_ref', + ) + .whereNull('refresh_state_references.target_entity_ref'), ) .select({ entityId: 'orphans.entity_id', diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts index e89d53f79f..8e2f8b2f6f 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts @@ -317,7 +317,9 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { try { await this.processingDatabase.transaction(async tx => { const n = await this.processingDatabase.deleteOrphanedEntities(tx); - this.logger.info(`Deleted ${n} orphaned entities`); + if (n > 0) { + this.logger.info(`Deleted ${n} orphaned entities`); + } }); } catch (error) { this.logger.warn(`Failed to delete orphaned entities`, error); diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index 93a37fb04a..4f011813e6 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -1729,6 +1729,17 @@ describe('DefaultEntitiesCatalog', () => { ], }, }); + + await expect( + catalog.facets({ + facets: ['kind'], + filter: { not: { key: 'metadata.name', values: ['two'] } }, + }), + ).resolves.toEqual({ + facets: { + kind: [{ value: 'k', count: 1 }], + }, + }); }, ); diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index 5fca950cac..c328c83823 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -64,43 +64,47 @@ const defaultSortField: EntityOrder = { const DEFAULT_LIMIT = 20; -function parsePagination(input?: EntityPagination): { - limit?: number; - offset?: number; -} { +function parsePagination(input?: EntityPagination): EntityPagination { if (!input) { return {}; } let { limit, offset } = input; - if (input.after !== undefined) { - let cursor; - try { - const json = Buffer.from(input.after, 'base64').toString('utf8'); - cursor = JSON.parse(json); - } catch { - throw new InputError('Malformed after cursor, could not be parsed'); + if (input.after === undefined) { + return { limit, offset }; + } + + let cursor; + try { + const json = Buffer.from(input.after, 'base64').toString('utf8'); + cursor = JSON.parse(json); + } catch { + throw new InputError('Malformed after cursor, could not be parsed'); + } + + if (cursor.limit !== undefined) { + if (!Number.isInteger(cursor.limit)) { + throw new InputError('Malformed after cursor, limit was not an number'); } - if (cursor.limit !== undefined) { - if (!Number.isInteger(cursor.limit)) { - throw new InputError('Malformed after cursor, limit was not an number'); - } - limit = cursor.limit; - } - if (cursor.offset !== undefined) { - if (!Number.isInteger(cursor.offset)) { - throw new InputError('Malformed after cursor, offset was not a number'); - } - offset = cursor.offset; + limit = cursor.limit; + } + + if (cursor.offset !== undefined) { + if (!Number.isInteger(cursor.offset)) { + throw new InputError('Malformed after cursor, offset was not a number'); } + offset = cursor.offset; } return { limit, offset }; } -function stringifyPagination(input: { limit: number; offset: number }) { - const json = JSON.stringify({ limit: input.limit, offset: input.offset }); +function stringifyPagination( + input: Required>, +): string { + const { limit, offset } = input; + const json = JSON.stringify({ limit, offset }); const base64 = Buffer.from(json, 'utf8').toString('base64'); return base64; } @@ -111,24 +115,21 @@ function addCondition( filter: EntitiesSearchFilter, negate: boolean = false, entityIdField = 'entity_id', -) { +): void { + const key = filter.key.toLowerCase(); + const values = filter.values?.map(v => v.toLowerCase()); + // NOTE(freben): This used to be a set of OUTER JOIN, which may seem to // make a lot of sense. However, it had abysmal performance on sqlite // when datasets grew large, so we're using IN instead. const matchQuery = db('search') .select('search.entity_id') - .where({ key: filter.key.toLowerCase() }) + .where({ key }) .andWhere(function keyFilter() { - if (filter.values) { - if (filter.values.length === 1) { - this.where({ value: filter.values[0].toLowerCase() }); - } else { - this.andWhere( - 'value', - 'in', - filter.values.map(v => v.toLowerCase()), - ); - } + if (values?.length === 1) { + this.where({ value: values.at(0) }); + } else if (values) { + this.andWhere('value', 'in', values); } }); queryBuilder.andWhere(entityIdField, negate ? 'not in' : 'in', matchQuery); @@ -159,16 +160,16 @@ function parseFilter( negate: boolean = false, entityIdField = 'entity_id', ): Knex.QueryBuilder { + if (isNegationEntityFilter(filter)) { + return parseFilter(filter.not, query, db, !negate, entityIdField); + } + if (isEntitiesSearchFilter(filter)) { return query.andWhere(function filterFunction() { addCondition(this, db, filter, negate, entityIdField); }); } - if (isNegationEntityFilter(filter)) { - return parseFilter(filter.not, query, db, !negate, entityIdField); - } - return query[negate ? 'andWhereNot' : 'andWhere'](function filterFunction() { if (isOrEntityFilter(filter)) { for (const subFilter of filter.anyOf ?? []) { @@ -678,10 +679,9 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { for (const facet of request.facets) { const dbQuery = db('search') - .join('final_entities', 'search.entity_id', 'final_entities.entity_id') .where('search.key', facet.toLocaleLowerCase('en-US')) - .count('search.entity_id as count') - .select({ value: 'search.original_value' }) + .whereNotNull('search.original_value') + .select({ value: 'search.original_value', count: db.raw('count(*)') }) .groupBy('search.original_value'); if (request?.filter) { diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md index 138edaee90..00d769e71e 100644 --- a/plugins/catalog-customized/CHANGELOG.md +++ b/plugins/catalog-customized/CHANGELOG.md @@ -1,5 +1,21 @@ # @internal/plugin-catalog-customized +## 0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-catalog@1.11.0 + +## 0.0.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + ## 0.0.10-next.1 ### Patch Changes diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json index 808f7a40e4..12f9bc584f 100644 --- a/plugins/catalog-customized/package.json +++ b/plugins/catalog-customized/package.json @@ -1,7 +1,7 @@ { "name": "@internal/plugin-catalog-customized", "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", - "version": "0.0.10-next.1", + "version": "0.0.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index eabfdaff12..277f0a70cf 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-graph +## 0.2.30 + +### Patch Changes + +- d446f8fb0a8: Expose all `EntityRelationsGraphProps` to Catalog Graph Page +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.30-next.1 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index b9ac5ea1c1..fd4d3d0114 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.30-next.1", + "version": "0.2.30", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 738a28f3af..50dee98951 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-catalog-import +## 0.9.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + +## 0.9.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.9.8-next.1 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 7e7113a16c..a6cad7a986 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.9.8-next.1", + "version": "0.9.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index a1ca2c37c6..5ed8a9aba1 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-catalog-node +## 1.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + ## 1.3.6-next.1 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 95136c2da1..7adf03eed2 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.3.6-next.1", + "version": "1.3.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index bd9d13ace5..7d96283320 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/plugin-catalog-react +## 1.6.0 + +### Minor Changes + +- 2258dcae970: Added an entity namespace filter and column on the default catalog page. + + If you have a custom version of the catalog page, you can add this filter in your CatalogPage code: + + ```ts + + + + + + /* if you want namespace picker */ + + + + + + + ``` + + The namespace column can be added using `createNamespaceColumn();`. This is only needed if you customized the columns for CatalogTable. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + +## 1.6.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + ## 1.6.0-next.1 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 37190aa4c8..569e9d5d8a 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.6.0-next.1", + "version": "1.6.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 1082396da1..41fdf9aad7 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,58 @@ # @backstage/plugin-catalog +## 1.11.0 + +### Minor Changes + +- 2258dcae970: Added an entity namespace filter and column on the default catalog page. + + If you have a custom version of the catalog page, you can add this filter in your CatalogPage code: + + ```ts + + + + + + /* if you want namespace picker */ + + + + + + + ``` + + The namespace column can be added using `createNamespaceColumn();`. This is only needed if you customized the columns for CatalogTable. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-search-common@1.2.3 + +## 1.11.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 1.11.0-next.1 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 0d5a9badcd..21983f762e 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.11.0-next.1", + "version": "1.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index d895633ad4..fed7193859 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cicd-statistics@0.1.20 + +## 0.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cicd-statistics@0.1.20-next.2 + ## 0.1.14-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 20d82e485f..ac719e1c1b 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.14-next.1", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index 3a802df672..b1b539c55e 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-cicd-statistics +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.20-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index a6a01ae05c..1eaebdf236 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.20-next.1", + "version": "0.1.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 8afa59660d..b2947ce517 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-circleci +## 0.3.18 + +### Patch Changes + +- 451b3cadb3d: Fixes row display for in progress jobs to not display trailing "took" +- 1c4958d905f: Hide empty time field data for queued builds which haven't started yet +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 683b43795c..87620319b2 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.18-next.1", + "version": "0.3.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index ba462e356c..3eb8b09596 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-cloudbuild +## 0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index 26a72a6c84..231e6c319c 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.18-next.1", + "version": "0.3.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index 405e65e814..1b732c2154 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-code-climate +## 0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 2edda59078..b2da33c3f6 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.18-next.1", + "version": "0.1.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index a63405bd75..10acc2a11a 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-code-coverage-backend +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 549e0a1b2c..4444287b23 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.11-next.1", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 7f5789d3a5..b514b137a1 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-code-coverage +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 412c7d3281..bb6fb411d5 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.11-next.1", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index 3c6338dfb0..242d8f6a4a 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-codescene +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 744634130c..13d5662812 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.13-next.0", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index e744ff73b1..059a476aed 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-config-schema +## 0.1.41 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.1.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.41-next.0 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 893048274e..3f1488178e 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.41-next.0", + "version": "0.1.41", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 89ba2ebaa0..63ac24c646 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-cost-insights +## 0.12.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-cost-insights-common@0.1.1 + +## 0.12.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.12.7-next.1 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 4855aae01a..8607bff31e 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.12.7-next.1", + "version": "0.12.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/devtools-backend/.eslintrc.js b/plugins/devtools-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/devtools-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md new file mode 100644 index 0000000000..45f9f7174d --- /dev/null +++ b/plugins/devtools-backend/CHANGELOG.md @@ -0,0 +1,33 @@ +# @backstage/plugin-devtools-backend + +## 0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0 + - @backstage/backend-common@0.18.5 + - @backstage/config-loader@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## 0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0-next.0 + - @backstage/config@1.0.7 diff --git a/plugins/devtools-backend/README.md b/plugins/devtools-backend/README.md new file mode 100644 index 0000000000..e505a04963 --- /dev/null +++ b/plugins/devtools-backend/README.md @@ -0,0 +1,56 @@ +# DevTools Backend + +Welcome to the DevTools backend plugin! This plugin provides data for the [DevTools frontend](../devtools/) features. + +## Setup + +Here's how to get the DevTools Backend up and running: + +1. First we need to add the `@backstage/plugin-devtools-backend` package to your backend: + + ```sh + # From the Backstage root directory + cd packages/backend + yarn add @backstage/plugin-devtools-backend + ``` + +2. Then we will create a new file named `packages/backend/src/plugins/devtools.ts`, and add the + following to it: + + ```ts + import { createRouter } from '@backstage/plugin-devtools-backend'; + import { Router } from 'express'; + import type { PluginEnvironment } from '../types'; + + export default function createPlugin( + env: PluginEnvironment, + ): Promise { + return createRouter({ + logger: env.logger, + config: env.config, + permissions: env.permissions, + }); + } + ``` + +3. Next we wire this into the overall backend router, edit `packages/backend/src/index.ts`: + + ```ts + import devTools from './plugins/devtools'; + // ... + async function main() { + // ... + // Add this line under the other lines that follow the useHotMemoize pattern + const devToolsEnv = useHotMemoize(module, () => createEnv('devtools')); + // ... + // Insert this line under the other lines that add their routers to apiRouter in the same way + apiRouter.use('/devtools', await devTools(devToolsEnv)); + ``` + +4. Now run `yarn start-backend` from the repo root +5. Finally open `http://localhost:7007/api/devtools/health` in a browser and it should return `{"status":"ok"}` + +## Links + +- [Frontend part of the plugin](../devtools/README.md) +- [The Backstage homepage](https://backstage.io) diff --git a/plugins/devtools-backend/api-report.md b/plugins/devtools-backend/api-report.md new file mode 100644 index 0000000000..e28f0697ab --- /dev/null +++ b/plugins/devtools-backend/api-report.md @@ -0,0 +1,39 @@ +## API Report File for "@backstage/plugin-devtools-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import { ConfigInfo } from '@backstage/plugin-devtools-common'; +import { DevToolsInfo } from '@backstage/plugin-devtools-common'; +import express from 'express'; +import { ExternalDependency } from '@backstage/plugin-devtools-common'; +import { Logger } from 'winston'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; + +// @public (undocumented) +export function createRouter(options: RouterOptions): Promise; + +// @public (undocumented) +export class DevToolsBackendApi { + constructor(logger: Logger, config: Config); + // (undocumented) + listConfig(): Promise; + // (undocumented) + listExternalDependencyDetails(): Promise; + // (undocumented) + listInfo(): Promise; +} + +// @public (undocumented) +export interface RouterOptions { + // (undocumented) + config: Config; + // (undocumented) + devToolsBackendApi?: DevToolsBackendApi; + // (undocumented) + logger: Logger; + // (undocumented) + permissions: PermissionEvaluator; +} +``` diff --git a/plugins/devtools-backend/config.d.ts b/plugins/devtools-backend/config.d.ts new file mode 100644 index 0000000000..15e70afcf8 --- /dev/null +++ b/plugins/devtools-backend/config.d.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2022 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. + */ +export interface Config { + /** + * DevTools configuration. + */ + devTools?: { + /** + * External dependency configuration. + */ + externalDependencies?: { + /** + * The list of endpoints to check. + */ + endpoints?: Array<{ + /** + * The name of the endpoint. + */ + name: string; + /** + * Type of check to perform; currently fetch or ping + */ + type: string; + /** + * The target of the endpoint; currently either a URL for fetch or server name for ping. + */ + target: string; + }>; + }; + }; +} diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json new file mode 100644 index 0000000000..77eaf43901 --- /dev/null +++ b/plugins/devtools-backend/package.json @@ -0,0 +1,63 @@ +{ + "name": "@backstage/plugin-devtools-backend", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/cli-common": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/config-loader": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-devtools-common": "workspace:^", + "@backstage/plugin-permission-common": "workspace:^", + "@backstage/plugin-permission-node": "workspace:^", + "@backstage/types": "workspace:^", + "@manypkg/get-packages": "^1.1.3", + "@types/express": "*", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "^3.0.0-rc.4", + "express": "^4.18.1", + "express-promise-router": "^4.1.0", + "fs-extra": "^10.0.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.7", + "ping": "^0.4.1", + "semver": "^7.3.2", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/minimist": "^1.2.0", + "@types/ping": "^0.4.1", + "@types/supertest": "^2.0.8", + "@types/yarnpkg__lockfile": "^1.1.4", + "msw": "^0.47.0", + "supertest": "^6.2.4" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts new file mode 100644 index 0000000000..efd0407b31 --- /dev/null +++ b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts @@ -0,0 +1,254 @@ +/* + * Copyright 2022 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 { Config, ConfigReader } from '@backstage/config'; +import { loadConfigSchema } from '@backstage/config-loader'; +import { + PackageDependency, + DevToolsInfo, + ExternalDependency, + Endpoint, + ExternalDependencyStatus, + ConfigInfo, +} from '@backstage/plugin-devtools-common'; + +import { JsonObject } from '@backstage/types'; +import { Logger } from 'winston'; +import fetch from 'node-fetch'; +import { findPaths } from '@backstage/cli-common'; +import { getPackages } from '@manypkg/get-packages'; +import ping from 'ping'; +import os from 'os'; +import fs from 'fs-extra'; +import { Lockfile } from '../util/Lockfile'; +import { memoize } from 'lodash'; +import { assertError } from '@backstage/errors'; + +/** @public */ +export class DevToolsBackendApi { + public constructor( + private readonly logger: Logger, + private readonly config: Config, + ) {} + + public async listExternalDependencyDetails(): Promise { + const result: ExternalDependency[] = []; + + const endpoints = this.config.getOptional( + 'devTools.externalDependencies.endpoints', + ); + if (!endpoints) { + // No external dependency endpoints configured + return result; + } + for (const endpoint of endpoints) { + this.logger?.info( + `Checking external dependency "${endpoint.name}" at "${endpoint.target}"`, + ); + + switch (endpoint.type) { + case 'ping': { + const pingResult = await this.pingExternalDependency(endpoint); + result.push(pingResult); + break; + } + case 'fetch': { + const fetchResult = await this.fetchExternalDependency(endpoint); + result.push(fetchResult); + break; + } + default: + return result; + } + } + + return result; + } + + private async fetchExternalDependency( + endpoint: Endpoint, + ): Promise { + let status; + let error; + + await fetch(endpoint.target) + .then(res => { + status = + res.status === 200 + ? ExternalDependencyStatus.healthy + : ExternalDependencyStatus.unhealthy; + this.logger.debug( + `Fetch for ${endpoint.name} resulted in status code "${res.status}"`, + ); + }) + .catch((err: Error) => { + this.logger.error(`Fetch failed for ${endpoint.name} - ${err.message}`); + error = err.message; + }); + + const result: ExternalDependency = { + name: endpoint.name, + type: endpoint.type, + target: endpoint.target, + status: status ?? ExternalDependencyStatus.unhealthy, + error: error ?? undefined, + }; + + return result; + } + + private async pingExternalDependency( + endpoint: Endpoint, + ): Promise { + const pingResult = await ping.promise.probe(endpoint.target); + + let error; + if ( + pingResult.packetLoss === '100.000' || + pingResult.packetLoss === 'unknown' + ) { + this.logger.error( + `Ping failed for ${endpoint.name} - ${pingResult.output}`, + ); + error = + pingResult.output === '' + ? `${endpoint.target} - Unknown` + : pingResult.output; + } + + this.logger.debug( + `Ping results for ${endpoint.name}: ${pingResult.output}`, + ); + + const result: ExternalDependency = { + name: endpoint.name, + type: endpoint.type, + target: endpoint.target, + status: pingResult.alive + ? ExternalDependencyStatus.healthy + : ExternalDependencyStatus.unhealthy, + error: error ?? undefined, + }; + + return result; + } + + public async listConfig(): Promise { + /* eslint-disable-next-line no-restricted-syntax */ + const paths = findPaths(__dirname); + + const { packages } = await getPackages(paths.targetDir); + const schemaFunc = async () => { + return await loadConfigSchema({ + dependencies: packages.map(p => p.packageJson.name), + }); + }; + + const schemaMemo = memoize(schemaFunc); + const schema = await schemaMemo(); + + const configInfo: ConfigInfo = { + config: undefined, + error: undefined, + }; + try { + const config = { + data: this.config.get() as JsonObject, + context: 'inline', + }; + const sanitizedConfigs = schema.process([config], { + ignoreSchemaErrors: false, + valueTransform: (value, context) => + context.visibility === 'secret' ? '' : value, + }); + + const data = ConfigReader.fromConfigs(sanitizedConfigs).get(); + configInfo.config = data; + } catch (error) { + assertError(error); + // The config is not valid for some reason but we want to be able to see it still + const config = { + data: this.config.get() as JsonObject, + context: 'inline', + }; + const sanitizedConfigs = schema.process([config], { + ignoreSchemaErrors: true, + valueTransform: (value, context) => + context.visibility === 'secret' ? '' : value, + }); + + const data = ConfigReader.fromConfigs(sanitizedConfigs).get(); + configInfo.config = data; + configInfo.error = { + name: error.name, + message: error.message, + messages: error.messages as string[] | undefined, + stack: error.stack, + }; + } + + return configInfo; + } + + public async listInfo(): Promise { + const operatingSystem = `${os.type} ${os.release} - ${os.platform}/${os.arch}`; + const nodeJsVersion = process.version; + + /* eslint-disable-next-line no-restricted-syntax */ + const paths = findPaths(__dirname); + const backstageFile = paths.resolveTargetRoot('backstage.json'); + let backstageJson = undefined; + if (fs.existsSync(backstageFile)) { + const buffer = await fs.readFile(backstageFile); + backstageJson = JSON.parse(buffer.toString()); + } + + const lockfilePath = paths.resolveTargetRoot('yarn.lock'); + const lockfile = await Lockfile.load(lockfilePath); + + const deps = [...lockfile.keys()].filter(n => n.startsWith('@backstage/')); + + const infoDependencies: PackageDependency[] = []; + for (const dep of deps) { + const versions = new Set(lockfile.get(dep)!.map(i => i.version)); + const infoDependency: PackageDependency = { + name: dep, + versions: [...versions].join(', '), + }; + infoDependencies.push(infoDependency); + } + + const info: DevToolsInfo = { + operatingSystem: operatingSystem ?? 'N/A', + nodeJsVersion: nodeJsVersion ?? 'N/A', + backstageVersion: + backstageJson && backstageJson.version ? backstageJson.version : 'N/A', + dependencies: infoDependencies, + }; + + return info; + } +} + +export function isValidUrl(url: string): boolean { + try { + // eslint-disable-next-line no-new + new URL(url); + return true; + } catch { + return false; + } +} diff --git a/plugins/devtools-backend/src/api/index.ts b/plugins/devtools-backend/src/api/index.ts new file mode 100644 index 0000000000..ed3390b113 --- /dev/null +++ b/plugins/devtools-backend/src/api/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { DevToolsBackendApi } from './DevToolsBackendApi'; diff --git a/plugins/devtools-backend/src/index.ts b/plugins/devtools-backend/src/index.ts new file mode 100644 index 0000000000..e1545e0022 --- /dev/null +++ b/plugins/devtools-backend/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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. + */ + +/** + * Backstage DevTools backend plugin that contains the API for retrieving package dependencies and current configuration which is used by the Backstage DevTools frontend plugin. + * + * @packageDocumentation + */ + +export { DevToolsBackendApi } from './api'; +export * from './service/router'; diff --git a/plugins/devtools-backend/src/run.ts b/plugins/devtools-backend/src/run.ts new file mode 100644 index 0000000000..d945aa13f0 --- /dev/null +++ b/plugins/devtools-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2022 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 { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/devtools-backend/src/service/router.test.ts b/plugins/devtools-backend/src/service/router.test.ts new file mode 100644 index 0000000000..f3c78242cf --- /dev/null +++ b/plugins/devtools-backend/src/service/router.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright 2022 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 { getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import express from 'express'; +import request from 'supertest'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { createRouter } from './router'; + +const mockedAuthorize: jest.MockedFunction = + jest.fn(); +const mockedPermissionQuery: jest.MockedFunction< + PermissionEvaluator['authorizeConditional'] +> = jest.fn(); + +const permissionEvaluator: PermissionEvaluator = { + authorize: mockedAuthorize, + authorizeConditional: mockedPermissionQuery, +}; + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + config: new ConfigReader({ + healthCheck: { + endpoint: [ + { + name: '', + type: '', + target: '', + }, + ], + }, + }), + permissions: permissionEvaluator, + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); diff --git a/plugins/devtools-backend/src/service/router.ts b/plugins/devtools-backend/src/service/router.ts new file mode 100644 index 0000000000..a346ad3183 --- /dev/null +++ b/plugins/devtools-backend/src/service/router.ts @@ -0,0 +1,130 @@ +/* + * Copyright 2022 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 { + AuthorizeResult, + PermissionEvaluator, +} from '@backstage/plugin-permission-common'; +import { + devToolsConfigReadPermission, + devToolsExternalDependenciesReadPermission, + devToolsInfoReadPermission, +} from '@backstage/plugin-devtools-common'; + +import { Config } from '@backstage/config'; +import { DevToolsBackendApi } from '../api'; +import { Logger } from 'winston'; +import { NotAllowedError } from '@backstage/errors'; +import Router from 'express-promise-router'; +import { errorHandler } from '@backstage/backend-common'; +import express from 'express'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; + +/** @public */ +export interface RouterOptions { + devToolsBackendApi?: DevToolsBackendApi; + logger: Logger; + config: Config; + permissions: PermissionEvaluator; +} + +/** @public */ +export async function createRouter( + options: RouterOptions, +): Promise { + const { logger, config, permissions } = options; + + const devToolsBackendApi = + options.devToolsBackendApi || new DevToolsBackendApi(logger, config); + + const router = Router(); + router.use(express.json()); + + router.get('/health', (_req, res) => { + res.status(200).json({ status: 'ok' }); + }); + + router.get('/info', async (req, response) => { + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + const decision = ( + await permissions.authorize( + [{ permission: devToolsInfoReadPermission }], + { + token, + }, + ) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + + const info = await devToolsBackendApi.listInfo(); + + response.status(200).json(info); + }); + + router.get('/config', async (req, response) => { + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + const decision = ( + await permissions.authorize( + [{ permission: devToolsConfigReadPermission }], + { + token, + }, + ) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + + const configList = await devToolsBackendApi.listConfig(); + + response.status(200).json(configList); + }); + + router.get('/external-dependencies', async (req, response) => { + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + const decision = ( + await permissions.authorize( + [{ permission: devToolsExternalDependenciesReadPermission }], + { + token, + }, + ) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + + const health = await devToolsBackendApi.listExternalDependencyDetails(); + + response.status(200).json(health); + }); + + router.use(errorHandler()); + return router; +} diff --git a/plugins/devtools-backend/src/service/standaloneServer.ts b/plugins/devtools-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..d2fdce169d --- /dev/null +++ b/plugins/devtools-backend/src/service/standaloneServer.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2022 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 { + ServerTokenManager, + SingleHostDiscovery, + createServiceBuilder, + loadBackendConfig, +} from '@backstage/backend-common'; + +import { Logger } from 'winston'; +import { Server } from 'http'; +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { createRouter } from './router'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'devtools-backend-backend' }); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const discovery = SingleHostDiscovery.fromConfig(config); + const tokenManager = ServerTokenManager.fromConfig(config, { + logger, + }); + const permissions = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + }); + logger.debug('Starting application server...'); + const router = await createRouter({ + logger, + config, + permissions, + }); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/devtools-backend', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/devtools-backend/src/setupTests.ts b/plugins/devtools-backend/src/setupTests.ts new file mode 100644 index 0000000000..813cdeaae3 --- /dev/null +++ b/plugins/devtools-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export {}; diff --git a/plugins/devtools-backend/src/util/Lockfile.ts b/plugins/devtools-backend/src/util/Lockfile.ts new file mode 100644 index 0000000000..52dbb847bc --- /dev/null +++ b/plugins/devtools-backend/src/util/Lockfile.ts @@ -0,0 +1,317 @@ +/* + * Copyright 2022 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 fs from 'fs-extra'; +import semver from 'semver'; +import { parseSyml, stringifySyml } from '@yarnpkg/parsers'; +import { stringify as legacyStringifyLockfile } from '@yarnpkg/lockfile'; + +const ENTRY_PATTERN = /^((?:@[^/]+\/)?[^@/]+)@(.+)$/; + +type LockfileData = { + [entry: string]: { + version: string; + resolved?: string; + integrity?: string; + dependencies?: { [name: string]: string }; + }; +}; + +type LockfileQueryEntry = { + range: string; + version: string; +}; + +/** Entries that have an invalid version range, for example an npm tag */ +type AnalyzeResultInvalidRange = { + name: string; + range: string; +}; + +/** Entries that can be deduplicated by bumping to an existing higher version */ +type AnalyzeResultNewVersion = { + name: string; + range: string; + oldVersion: string; + newVersion: string; +}; + +/** Entries that would need a dependency update in package.json to be deduplicated */ +type AnalyzeResultNewRange = { + name: string; + oldRange: string; + newRange: string; + oldVersion: string; + newVersion: string; +}; + +type AnalyzeResult = { + invalidRanges: AnalyzeResultInvalidRange[]; + newVersions: AnalyzeResultNewVersion[]; + newRanges: AnalyzeResultNewRange[]; +}; + +function parseLockfile(lockfileContents: string) { + try { + return { + object: parseSyml(lockfileContents), + type: 'success', + }; + } catch (err) { + return { + object: null, + type: err, + }; + } +} + +// the new yarn header is handled out of band of the parsing +// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-core/sources/Project.ts#L1741-L1746 +const NEW_HEADER = `${[ + `# This file is generated by running "yarn install" inside your project.\n`, + `# Manual changes might be lost - proceed with caution!\n`, +].join(``)}\n`; + +function stringifyLockfile(data: LockfileData, legacy: boolean) { + return legacy + ? legacyStringifyLockfile(data) + : NEW_HEADER + stringifySyml(data); +} +// taken from yarn parser package +// https://github.com/yarnpkg/berry/blob/0c5974f193a9397630e9aee2b3876cca62611149/packages/yarnpkg-parsers/sources/syml.ts#L136 +const LEGACY_REGEX = /^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i; + +// these are special top level yarn keys. +// https://github.com/yarnpkg/berry/blob/9bd61fbffb83d0b8166a9cc26bec3a58743aa453/packages/yarnpkg-parsers/sources/syml.ts#L9 +const SPECIAL_OBJECT_KEYS = [ + `__metadata`, + `version`, + `resolution`, + `dependencies`, + `peerDependencies`, + `dependenciesMeta`, + `peerDependenciesMeta`, + `binaries`, +]; + +export class Lockfile { + static async load(path: string) { + const lockfileContents = await fs.readFile(path, 'utf8'); + const legacy = LEGACY_REGEX.test(lockfileContents); + const lockfile = parseLockfile(lockfileContents); + if (lockfile.type !== 'success') { + throw new Error(`Failed yarn.lock parse with ${lockfile.type}`); + } + + const data = lockfile.object as LockfileData; + const packages = new Map(); + + for (const [key, value] of Object.entries(data)) { + if (SPECIAL_OBJECT_KEYS.includes(key)) continue; + + const [, name, range] = ENTRY_PATTERN.exec(key) ?? []; + if (!name) { + throw new Error(`Failed to parse yarn.lock entry '${key}'`); + } + + let queries = packages.get(name); + if (!queries) { + queries = []; + packages.set(name, queries); + } + queries.push({ range, version: value.version }); + } + + return new Lockfile(path, packages, data, legacy); + } + + private constructor( + private readonly path: string, + private readonly packages: Map, + private readonly data: LockfileData, + private readonly legacy: boolean = false, + ) {} + + /** Get the entries for a single package in the lockfile */ + get(name: string): LockfileQueryEntry[] | undefined { + return this.packages.get(name); + } + + /** Returns the name of all packages available in the lockfile */ + keys(): IterableIterator { + return this.packages.keys(); + } + + /** Analyzes the lockfile to identify possible actions and warnings for the entries */ + analyze(options?: { filter?: (name: string) => boolean }): AnalyzeResult { + const { filter } = options ?? {}; + const result: AnalyzeResult = { + invalidRanges: [], + newVersions: [], + newRanges: [], + }; + + for (const [name, allEntries] of this.packages) { + if (filter && !filter(name)) { + continue; + } + + // Get rid of and signal any invalid ranges upfront + const invalid = allEntries.filter(e => !semver.validRange(e.range)); + result.invalidRanges.push( + ...invalid.map(({ range }) => ({ name, range })), + ); + + // Grab all valid entries, if there aren't at least 2 different valid ones we're done + const entries = allEntries.filter(e => semver.validRange(e.range)); + if (entries.length < 2) { + continue; + } + + // Find all versions currently in use + const versions = Array.from(new Set(entries.map(e => e.version))).sort( + (v1, v2) => semver.rcompare(v1, v2), + ); + + // If we're not using at least 2 different versions we're done + if (versions.length < 2) { + continue; + } + + const acceptedVersions = new Set(); + for (const { version, range } of entries) { + // Finds the highest matching version from the the known versions + // TODO(Rugvip): We may want to select the version that satisfies the most ranges rather than the highest one + const acceptedVersion = versions.find(v => semver.satisfies(v, range)); + if (!acceptedVersion) { + throw new Error( + `No existing version was accepted for range ${range}, searching through ${versions}, for package ${name}`, + ); + } + + if (acceptedVersion !== version) { + result.newVersions.push({ + name, + range, + newVersion: acceptedVersion, + oldVersion: version, + }); + } + + acceptedVersions.add(acceptedVersion); + } + + // If all ranges were able to accept the same version, we're done + if (acceptedVersions.size === 1) { + continue; + } + + // Find the max version that we may want bump older packages to + const maxVersion = Array.from(acceptedVersions).sort(semver.rcompare)[0]; + // Find all existing ranges that satisfy the new max version, and pick the one that + // results in the highest minimum allowed version, usually being the more specific one + const maxEntry = entries + .filter(e => semver.satisfies(maxVersion, e.range)) + .map(e => ({ e, min: semver.minVersion(e.range) })) + .filter(p => p.min) + .sort((a, b) => semver.rcompare(a.min!, b.min!))[0]?.e; + if (!maxEntry) { + throw new Error( + `No entry found that satisfies max version '${maxVersion}'`, + ); + } + + // Find all entries that don't satisfy the max version + for (const { version, range } of entries) { + if (semver.satisfies(maxVersion, range)) { + continue; + } + + result.newRanges.push({ + name, + oldRange: range, + newRange: maxEntry.range, + oldVersion: version, + newVersion: maxVersion, + }); + } + } + + return result; + } + + remove(name: string, range: string): boolean { + const query = `${name}@${range}`; + const existed = Boolean(this.data[query]); + delete this.data[query]; + + const newEntries = this.packages.get(name)?.filter(e => e.range !== range); + if (newEntries) { + this.packages.set(name, newEntries); + } + + return existed; + } + + /** Modifies the lockfile by bumping packages to the suggested versions */ + replaceVersions(results: AnalyzeResultNewVersion[]) { + for (const { name, range, oldVersion, newVersion } of results) { + const query = `${name}@${range}`; + + // Update the backing data + const entryData = this.data[query]; + if (!entryData) { + throw new Error(`No entry data for ${query}`); + } + if (entryData.version !== oldVersion) { + throw new Error( + `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, + ); + } + + // Modifying the data in the entry is not enough, we need to reference an existing version object + const matchingEntry = Object.entries(this.data).find( + ([q, e]) => q.startsWith(`${name}@`) && e.version === newVersion, + ); + if (!matchingEntry) { + throw new Error( + `No matching entry found for ${name} at version ${newVersion}`, + ); + } + this.data[query] = matchingEntry[1]; + + // Update our internal data structure + const entry = this.packages.get(name)?.find(e => e.range === range); + if (!entry) { + throw new Error(`No entry data for ${query}`); + } + if (entry.version !== oldVersion) { + throw new Error( + `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, + ); + } + entry.version = newVersion; + } + } + + async save() { + await fs.writeFile(this.path, this.toString(), 'utf8'); + } + + toString() { + return stringifyLockfile(this.data, this.legacy); + } +} diff --git a/plugins/devtools-common/.eslintrc.js b/plugins/devtools-common/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/devtools-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/devtools-common/CHANGELOG.md b/plugins/devtools-common/CHANGELOG.md new file mode 100644 index 0000000000..6a566d0a67 --- /dev/null +++ b/plugins/devtools-common/CHANGELOG.md @@ -0,0 +1,19 @@ +# @backstage/plugin-devtools-common + +## 0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## 0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! diff --git a/plugins/devtools-common/README.md b/plugins/devtools-common/README.md new file mode 100644 index 0000000000..5be5e58773 --- /dev/null +++ b/plugins/devtools-common/README.md @@ -0,0 +1,3 @@ +# DevTools Common + +Common types and permissions for the DevTools plugin. diff --git a/plugins/devtools-common/api-report.md b/plugins/devtools-common/api-report.md new file mode 100644 index 0000000000..7e38ff05b0 --- /dev/null +++ b/plugins/devtools-common/api-report.md @@ -0,0 +1,72 @@ +## API Report File for "@backstage/plugin-devtools-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BasicPermission } from '@backstage/plugin-permission-common'; +import { JsonValue } from '@backstage/types'; + +// @public (undocumented) +export type ConfigError = { + name: string; + message: string; + messages?: string[]; + stack?: string; +}; + +// @public (undocumented) +export type ConfigInfo = { + config?: JsonValue; + error?: ConfigError; +}; + +// @public (undocumented) +export const devToolsAdministerPermission: BasicPermission; + +// @public (undocumented) +export const devToolsConfigReadPermission: BasicPermission; + +// @public (undocumented) +export const devToolsExternalDependenciesReadPermission: BasicPermission; + +// @public (undocumented) +export type DevToolsInfo = { + operatingSystem: string; + nodeJsVersion: string; + backstageVersion: string; + dependencies: PackageDependency[]; +}; + +// @public (undocumented) +export const devToolsInfoReadPermission: BasicPermission; + +// @public (undocumented) +export type Endpoint = { + name: string; + type: string; + target: string; +}; + +// @public (undocumented) +export type ExternalDependency = { + name: string; + type: string; + target: string; + status: string; + error?: string; +}; + +// @public (undocumented) +export enum ExternalDependencyStatus { + // (undocumented) + healthy = 'Healthy', + // (undocumented) + unhealthy = 'Unhealthy', +} + +// @public (undocumented) +export type PackageDependency = { + name: string; + versions: string; +}; +``` diff --git a/plugins/devtools-common/package.json b/plugins/devtools-common/package.json new file mode 100644 index 0000000000..0e114e39b9 --- /dev/null +++ b/plugins/devtools-common/package.json @@ -0,0 +1,35 @@ +{ + "name": "@backstage/plugin-devtools-common", + "description": "Common functionalities for the devtools plugin", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "common-library" + }, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/plugin-permission-common": "workspace:^", + "@backstage/types": "workspace:^" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/devtools-common/src/index.ts b/plugins/devtools-common/src/index.ts new file mode 100644 index 0000000000..be7426394b --- /dev/null +++ b/plugins/devtools-common/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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. + */ + +/** + * Common types and permissions for the DevTools frontend and backend plugins. + * + * @packageDocumentation + */ + +export * from './types'; +export * from './permissions'; diff --git a/plugins/devtools-common/src/permissions.ts b/plugins/devtools-common/src/permissions.ts new file mode 100644 index 0000000000..ae62cfdc19 --- /dev/null +++ b/plugins/devtools-common/src/permissions.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2022 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 { createPermission } from '@backstage/plugin-permission-common'; + +/** + * @public + */ +export const devToolsAdministerPermission = createPermission({ + name: 'devtools.administer', + attributes: { action: 'read' }, +}); + +/** + * @public + */ +export const devToolsInfoReadPermission = createPermission({ + name: 'devtools.info', + attributes: { action: 'read' }, +}); + +/** + * @public + */ +export const devToolsConfigReadPermission = createPermission({ + name: 'devtools.config', + attributes: { action: 'read' }, +}); + +/** + * @public + */ +export const devToolsExternalDependenciesReadPermission = createPermission({ + name: 'devtools.external-dependencies', + attributes: { action: 'read' }, +}); diff --git a/plugins/devtools-common/src/setupTests.ts b/plugins/devtools-common/src/setupTests.ts new file mode 100644 index 0000000000..813cdeaae3 --- /dev/null +++ b/plugins/devtools-common/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export {}; diff --git a/plugins/devtools-common/src/types.ts b/plugins/devtools-common/src/types.ts new file mode 100644 index 0000000000..d08232b155 --- /dev/null +++ b/plugins/devtools-common/src/types.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2022 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 { JsonValue } from '@backstage/types'; + +/** @public */ +export type Endpoint = { + name: string; + type: string; + target: string; +}; + +/** @public */ +export type ExternalDependency = { + name: string; + type: string; + target: string; + status: string; + error?: string; +}; + +/** @public */ +export type DevToolsInfo = { + operatingSystem: string; + nodeJsVersion: string; + backstageVersion: string; + dependencies: PackageDependency[]; +}; + +/** @public */ +export type PackageDependency = { + name: string; + versions: string; +}; + +/** @public */ +export enum ExternalDependencyStatus { + healthy = 'Healthy', + unhealthy = 'Unhealthy', +} + +/** @public */ +export type ConfigInfo = { + config?: JsonValue; + error?: ConfigError; +}; + +/** @public */ +export type ConfigError = { + name: string; + message: string; + messages?: string[]; + stack?: string; +}; diff --git a/plugins/devtools/.eslintrc.js b/plugins/devtools/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/devtools/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md new file mode 100644 index 0000000000..2e0e2a2de0 --- /dev/null +++ b/plugins/devtools/CHANGELOG.md @@ -0,0 +1,33 @@ +# @backstage/plugin-devtools + +## 0.1.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0 + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-react@0.4.12 + +## 0.1.0-next.0 + +### Minor Changes + +- 347aeca204c: Introduced the DevTools plugin, checkout the plugin's [`README.md`](https://github.com/backstage/backstage/tree/master/plugins/devtools) for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-devtools-common@0.1.0-next.0 + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 diff --git a/plugins/devtools/README.md b/plugins/devtools/README.md new file mode 100644 index 0000000000..fc9f1f7312 --- /dev/null +++ b/plugins/devtools/README.md @@ -0,0 +1,375 @@ +# DevTools + +Welcome to the DevTools plugin! This plugin helps elevate useful information about a Backstage instance through the frontend, which can be helpful for an integrator for troubleshooting, reviewing, and understanding their installation. + +## Features + +The DevTools plugin comes with two tabs out of the box. + +### Info + +Lists helpful information about your current running Backstage instance such as: OS, NodeJS version, Backstage version, and package versions. + +![Example of Info tab](./docs/devtools-info-tab.png) + +### Config + +Lists the configuration being used by your current running Backstage instance. + +![Example of Config tab](./docs/devtools-config-tab.png) + +## Optional Features + +The DevTools plugin can be setup with other tabs with additional helpful features. + +### External Dependencies + +Lists the status of configured External Dependencies based on your current running Backstage instance's ability to reach them. + +![Example of external dependencies tab](./docs/devtools-external-dependencies.png) + +## Setup + +The following sections will help you get the DevTools plugin setup and running. + +### Backend + +You need to setup the [DevTools backend plugin](../devtools-backend/README.md) before you move forward with any of the following steps if you haven't already. + +### Frontend + +To setup the DevTools frontend you'll need to do the following steps: + +1. First we need to add the `@backstage/plugin-devtools` package to your frontend app: + + ```sh + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-devtools + ``` + +2. Now open the `packages/app/src/App.tsx` file +3. Then after all the import statements add the following line: + + ```ts + import { DevToolsPage } from '@backstage/plugin-devtools'; + ``` + +4. In this same file just before the closing ``, this will be near the bottom of the file, add this line: + + ```ts + } /> + ``` + +5. Next open the `packages/app/src/components/Root/Root.tsx` file +6. We want to add this icon import after all the existing import statements: + + ```ts + import BuildIcon from '@material-ui/icons/Build'; + ``` + +7. Then add this line just after the `` line: + + ```ts + + ``` + +8. Now run `yarn dev` from the root of your project and you should see the DevTools option show up just below Settings in your sidebar and clicking on it will get you to the [Info tab](#info) + +## Customizing + +The DevTools plugin has been designed so that you can customize the tabs to suite your needs. You may only want some or none of the out of the box tabs or you may want to add your own. The following sections explains how to do that (assuming you've already done the [setup steps](#setup)). As part of this example we'll also be showing how you can add the optional [External Dependencies](#external-dependencies) tab. + +1. In the `packages/app/src/components` folder create a new sub-folder called `devtools` +2. Then in this new `devtools` folder add a file called `CustomDevToolsPage.tsx` +3. In the `CustomDevToolsPage.tsx` file add the following content: + + ```tsx + import { + ConfigContent, + ExternalDependenciesContent, + InfoContent, + } from '@backstage/plugin-devtools'; + import { DevToolsLayout } from '@backstage/plugin-devtools'; + import React from 'react'; + + export const DevToolsPage = () => { + return ( + + + + + + + + + + + + ); + }; + + export const customDevToolsPage = ; + ``` + +4. Now open the `packages/app/src/App.tsx` file and add the following import after all the existing import statements: + + ```ts + import { customDevToolsPage } from './components/devtools/CustomDevToolsPage'; + ``` + +5. Then we need to adjust our route as follows + + ```diff + - } /> + + } > + + {customDevToolsPage} + + + ``` + +6. Now run `yarn dev` from the root of your project. When you go to the DevTools you'll now see you have a third tab for [External Dependencies](#external-dependencies) + +With this setup you can add or remove the tabs as you'd like or add your own simply by editing your `CustomDevToolsPage.tsx` file + +## Permissions + +The DevTools plugin supports the [permissions framework](https://backstage.io/docs/permissions/overview), the following sections outline how you can use them with the assumption that you have the permissions framework setup and working. + +**Note:** These sections are intended as guidance and are completely optional. The DevTools plugin will work with the permission framework off or on without any specific policy setup. + +### Secure Sidebar Option + +To use the permission framework to secure the DevTools sidebar option you'll want to do the following: + +1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app: + + ```sh + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-devtools + ``` + +2. Then open the `packages/app/src/components/Root/Root.tsx` file +3. The add these imports after all the existing import statements: + + ```ts + import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common'; + import { RequirePermission } from '@backstage/plugin-permission-react'; + ``` + +4. Then make the following change: + + ```diff + - + + }> + + + + + ``` + +### Secure the DevTools Route + +To use the permission framework to secure the DevTools route you'll want to do the following: + +1. First we need to add the `@backstage/plugin-devtools-common` package to your frontend app (skip this step if you've already done this): + + ```sh + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-devtools-common + ``` + +2. Then open the `packages/app/src/App.tsx` file +3. The add this import after all the existing import statements: + + ```ts + import { devToolsAdministerPermission } from '@backstage/plugin-devtools-common'; + ``` + +4. Then make the following change: + + ```diff + - } /> + + + + + + + + } + + /> + ``` + +Note: if you are using a `customDevToolsPage` as per the [Customizing](#customizing) documentation the changes for Step 4 will be: + +```diff +- } /> ++ ++ ++ ++ } ++ > ++ {customDevToolsPage} ++ +``` + +### Permission Policy + +Here is an example permission policy that you might use to secure the DevTools plugin: + +```ts +// packages/backend/src/plugins/permission.ts + +class TestPermissionPolicy implements PermissionPolicy { + async handle(request: PolicyQuery): Promise { + if (isPermission(request.permission, devToolsAdministerPermission)) { + if ( + user?.identity.ownershipEntityRefs.includes( + 'group:default/backstage-admins', + ) + ) { + return { result: AuthorizeResult.ALLOW }; + } + return { result: AuthorizeResult.DENY }; + } + + if (isPermission(request.permission, devToolsInfoReadPermission)) { + if ( + user?.identity.ownershipEntityRefs.includes( + 'group:default/backstage-admins', + ) + ) { + return { result: AuthorizeResult.ALLOW }; + } + return { result: AuthorizeResult.DENY }; + } + + if (isPermission(request.permission, devToolsConfigReadPermission)) { + if ( + user?.identity.ownershipEntityRefs.includes( + 'group:default/backstage-admins', + ) + ) { + return { result: AuthorizeResult.ALLOW }; + } + return { result: AuthorizeResult.DENY }; + } + + if ( + isPermission( + request.permission, + devToolsExternalDependenciesReadPermission, + ) + ) { + if ( + user?.identity.ownershipEntityRefs.includes( + 'group:default/backstage-admins', + ) + ) { + return { result: AuthorizeResult.ALLOW }; + } + return { result: AuthorizeResult.DENY }; + } + + return { result: AuthorizeResult.ALLOW }; + } +} +``` + +To use this policy you'll need to make sure to add the `@backstage/plugin-devtools-common` package to your backend you can do that by running this command: + +```sh +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-devtools-common +``` + +You'll also need to add these imports: + +```ts +import { + devToolsAdministerPermission, + devToolsConfigReadPermission, + devToolsExternalDependenciesReadPermission, + devToolsInfoReadPermission, +} from '@backstage/plugin-devtools-common'; +``` + +**Note:** The group "group:default/backstage-admins" is simply an example and does not exist. You can point this to any group you have in your catalog instead. + +### Customizing with Permissions + +If you followed the [Customizing](#customizing) documentation and want to use permission there this is what your `CustomDevToolsPage.tsx` would look like: + +```tsx +import { + ConfigContent, + ExternalDependenciesContent, + InfoContent, +} from '@backstage/plugin-devtools'; +import { DevToolsLayout } from '@backstage/plugin-devtools'; +import { + devToolsConfigReadPermission, + devToolsExternalDependenciesReadPermission, + devToolsInfoReadPermission, +} from '@backstage/plugin-devtools-common'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import React from 'react'; + +const DevToolsPage = () => { + return ( + + + + + + + + + + + + + + + + + + ); +}; + +export const customDevToolsPage = ; +``` + +## Configuration + +The following sections outline the configuration for the DevTools plugin + +### External Dependencies Configuration + +If you decide to use the External Dependencies tab then you'll need to setup the configuration for it in your `app-config.yaml`, if there is no config setup then the tab will be empty. Here's an example: + +```yaml +devTools: + externalDependencies: + endpoints: + - name: 'Google' + type: 'fetch' + target: 'https://google.ca' + - name: 'Google Public DNS' + type: 'ping' + target: '8.8.8.8' +``` + +Configuration details: + +- `endpoints` is an array +- `name` is the friendly name for your endpoint +- `type` can be either `ping` or `fetch` and will perform the respective action on the `target` +- `target` is either a URL or server that you want to trigger a `type` action on diff --git a/plugins/devtools/api-report.md b/plugins/devtools/api-report.md new file mode 100644 index 0000000000..c9cfbf77e5 --- /dev/null +++ b/plugins/devtools/api-report.md @@ -0,0 +1,57 @@ +## API Report File for "@backstage/plugin-devtools" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { default as default_2 } from 'react'; +import { RouteRef } from '@backstage/core-plugin-api'; +import { TabProps } from '@material-ui/core'; + +// @public (undocumented) +export const ConfigContent: () => JSX.Element; + +// @public +export const DevToolsLayout: { + ({ children }: DevToolsLayoutProps): JSX.Element; + Route: (props: SubRoute) => null; +}; + +// @public (undocumented) +export type DevToolsLayoutProps = { + children?: default_2.ReactNode; +}; + +// @public (undocumented) +export const DevToolsPage: () => JSX.Element; + +// @public (undocumented) +export const devToolsPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; + +// @public (undocumented) +export const ExternalDependenciesContent: () => JSX.Element; + +// @public (undocumented) +export const InfoContent: () => JSX.Element; + +// @public (undocumented) +export type SubRoute = { + path: string; + title: string; + children: JSX.Element; + tabProps?: TabProps< + default_2.ElementType, + { + component?: default_2.ElementType; + } + >; +}; +``` diff --git a/plugins/devtools/dev/index.tsx b/plugins/devtools/dev/index.tsx new file mode 100644 index 0000000000..00c966a801 --- /dev/null +++ b/plugins/devtools/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2022 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 React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { devToolsPlugin, DevToolsPage } from '../src/plugin'; + +createDevApp() + .registerPlugin(devToolsPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/devtools', + }) + .render(); diff --git a/plugins/devtools/docs/devtools-config-tab.png b/plugins/devtools/docs/devtools-config-tab.png new file mode 100644 index 0000000000..b5c22f691b Binary files /dev/null and b/plugins/devtools/docs/devtools-config-tab.png differ diff --git a/plugins/devtools/docs/devtools-external-dependencies.png b/plugins/devtools/docs/devtools-external-dependencies.png new file mode 100644 index 0000000000..9356d83ef5 Binary files /dev/null and b/plugins/devtools/docs/devtools-external-dependencies.png differ diff --git a/plugins/devtools/docs/devtools-info-tab.png b/plugins/devtools/docs/devtools-info-tab.png new file mode 100644 index 0000000000..739045a77f Binary files /dev/null and b/plugins/devtools/docs/devtools-info-tab.png differ diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json new file mode 100644 index 0000000000..d5bd0c567a --- /dev/null +++ b/plugins/devtools/package.json @@ -0,0 +1,64 @@ +{ + "name": "@backstage/plugin-devtools", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/devtools" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-devtools-common": "workspace:^", + "@backstage/plugin-permission-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@backstage/types": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "react-json-view": "^1.21.3", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0", + "react": "^16.13.1 || ^17.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^0.47.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/devtools/src/api/DevToolsApi.ts b/plugins/devtools/src/api/DevToolsApi.ts new file mode 100644 index 0000000000..ff58a4ea16 --- /dev/null +++ b/plugins/devtools/src/api/DevToolsApi.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2022 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 { createApiRef } from '@backstage/core-plugin-api'; +import { + ConfigInfo, + DevToolsInfo, + ExternalDependency, +} from '@backstage/plugin-devtools-common'; + +export const devToolsApiRef = createApiRef({ + id: 'plugin.devtools.service', +}); + +export interface DevToolsApi { + getConfig(): Promise; + getExternalDependencies(): Promise; + getInfo(): Promise; +} diff --git a/plugins/devtools/src/api/DevToolsClient.ts b/plugins/devtools/src/api/DevToolsClient.ts new file mode 100644 index 0000000000..0be8294b3f --- /dev/null +++ b/plugins/devtools/src/api/DevToolsClient.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2022 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 { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { + ConfigInfo, + DevToolsInfo, + ExternalDependency, +} from '@backstage/plugin-devtools-common'; +import { ResponseError } from '@backstage/errors'; +import { DevToolsApi } from './DevToolsApi'; + +export class DevToolsClient implements DevToolsApi { + private readonly discoveryApi: DiscoveryApi; + private readonly identityApi: IdentityApi; + + public constructor(options: { + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.discoveryApi = options.discoveryApi; + this.identityApi = options.identityApi; + } + + public async getConfig(): Promise { + const urlSegment = 'config'; + + const configInfo = await this.get(urlSegment); + return configInfo; + } + + public async getExternalDependencies(): Promise< + ExternalDependency[] | undefined + > { + const urlSegment = 'external-dependencies'; + + const externalDependencies = await this.get< + ExternalDependency[] | undefined + >(urlSegment); + return externalDependencies; + } + + public async getInfo(): Promise { + const urlSegment = 'info'; + + const info = await this.get(urlSegment); + return info; + } + + private async get(path: string): Promise { + const baseUrl = `${await this.discoveryApi.getBaseUrl('devtools')}/`; + const url = new URL(path, baseUrl); + + const { token } = await this.identityApi.getCredentials(); + const response = await fetch(url.toString(), { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + return response.json() as Promise; + } +} diff --git a/plugins/devtools/src/api/index.ts b/plugins/devtools/src/api/index.ts new file mode 100644 index 0000000000..6bea0a07aa --- /dev/null +++ b/plugins/devtools/src/api/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 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. + */ + +export * from './DevToolsApi'; +export * from './DevToolsClient'; diff --git a/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx b/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx new file mode 100644 index 0000000000..66129b5dae --- /dev/null +++ b/plugins/devtools/src/components/Content/ConfigContent/ConfigContent.tsx @@ -0,0 +1,95 @@ +/* + * Copyright 2022 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 { Progress, WarningPanel } from '@backstage/core-components'; +import { + Box, + createStyles, + makeStyles, + Paper, + Theme, + Typography, + useTheme, +} from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; +import ReactJson from 'react-json-view'; +import { useConfig } from '../../../hooks'; +import { ConfigError } from '@backstage/plugin-devtools-common'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + warningStyle: { + paddingBottom: theme.spacing(2), + }, + paperStyle: { + padding: theme.spacing(2), + }, + }), +); + +export const WarningContent = ({ error }: { error: ConfigError }) => { + if (!error.messages) { + return {error.message}; + } + + const messages = error.messages as string[]; + + return ( + + {messages.map(message => ( + {message} + ))} + + ); +}; + +/** @public */ +export const ConfigContent = () => { + const classes = useStyles(); + const theme = useTheme(); + const { configInfo, loading, error } = useConfig(); + + if (loading) { + return ; + } else if (error) { + return {error.message}; + } + + if (!configInfo) { + return Unable to load config data; + } + + return ( + + {configInfo && configInfo.error && ( + + + + + + )} + + + + + ); +}; diff --git a/plugins/devtools/src/components/Content/ConfigContent/index.ts b/plugins/devtools/src/components/Content/ConfigContent/index.ts new file mode 100644 index 0000000000..b1cc671de8 --- /dev/null +++ b/plugins/devtools/src/components/Content/ConfigContent/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { ConfigContent } from './ConfigContent'; diff --git a/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx b/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx new file mode 100644 index 0000000000..a5dd825fe5 --- /dev/null +++ b/plugins/devtools/src/components/Content/ExternalDependenciesContent/ExternalDependenciesContent.tsx @@ -0,0 +1,140 @@ +/* + * Copyright 2022 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 { + Progress, + StatusError, + StatusOK, + StatusWarning, + Table, + TableColumn, +} from '@backstage/core-components'; +import { ExternalDependency } from '@backstage/plugin-devtools-common'; +import { + Box, + createStyles, + Grid, + makeStyles, + Paper, + Theme, + Typography, +} from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; +import { useExternalDependencies } from '../../../hooks'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + paperStyle: { + padding: theme.spacing(2), + }, + }), +); + +export const getExternalDependencyStatus = ( + result: Partial | undefined, +) => { + switch (result?.status) { + case 'Healthy': + return ( + + {result.status} + + ); + case 'Unhealthy': + return ( + + {`${result.status}`} + + ); + case undefined: + default: + return ( + + Unknown + + ); + } +}; + +const columns: TableColumn[] = [ + { + title: 'Name', + width: 'auto', + field: 'name', + }, + { + title: 'Target', + width: 'auto', + field: 'target', + }, + { + title: 'Type', + width: 'auto', + field: 'type', + }, + { + title: 'Status', + width: 'auto', + render: (row: Partial) => ( + + + + {getExternalDependencyStatus(row)} + + + {row.error && {row.error}} + + ), + }, +]; + +/** @public */ +export const ExternalDependenciesContent = () => { + const classes = useStyles(); + const { externalDependencies, loading, error } = useExternalDependencies(); + + if (loading) { + return ; + } else if (error) { + return {error.message}; + } + + if (!externalDependencies || externalDependencies.length === 0) { + return ( + + + No external dependencies found + + + ); + } + + return ( + + ); +}; diff --git a/plugins/devtools/src/components/Content/ExternalDependenciesContent/index.ts b/plugins/devtools/src/components/Content/ExternalDependenciesContent/index.ts new file mode 100644 index 0000000000..bf747f3065 --- /dev/null +++ b/plugins/devtools/src/components/Content/ExternalDependenciesContent/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { ExternalDependenciesContent } from './ExternalDependenciesContent'; diff --git a/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx b/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx new file mode 100644 index 0000000000..32f35600f2 --- /dev/null +++ b/plugins/devtools/src/components/Content/InfoContent/BackstageLogoIcon.tsx @@ -0,0 +1,25 @@ +/* + * Copyright 2022 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 { SvgIcon, SvgIconProps } from '@material-ui/core'; + +import React from 'react'; + +export const BackstageLogoIcon = (props: SvgIconProps) => ( + + + +); diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx new file mode 100644 index 0000000000..7a0ebb3e06 --- /dev/null +++ b/plugins/devtools/src/components/Content/InfoContent/InfoContent.tsx @@ -0,0 +1,138 @@ +/* + * Copyright 2022 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 { Progress } from '@backstage/core-components'; +import { + Avatar, + Box, + createStyles, + Divider, + List, + ListItem, + ListItemAvatar, + ListItemText, + makeStyles, + Paper, + Theme, +} from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; +import { useInfo } from '../../../hooks'; +import { InfoDependenciesTable } from './InfoDependenciesTable'; +import DescriptionIcon from '@material-ui/icons/Description'; +import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard'; +import { BackstageLogoIcon } from './BackstageLogoIcon'; +import FileCopyIcon from '@material-ui/icons/FileCopy'; +import { DevToolsInfo } from '@backstage/plugin-devtools-common'; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + paperStyle: { + marginBottom: theme.spacing(2), + }, + flexContainer: { + display: 'flex', + flexDirection: 'row', + padding: 0, + }, + copyButton: { + float: 'left', + margin: theme.spacing(2), + }, + }), +); + +const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => { + if (about) { + let formatted = `OS: ${about.operatingSystem}\nnode: ${about.nodeJsVersion}\nbackstage: ${about.backstageVersion}\nDependencies:\n`; + const deps = about.dependencies; + for (const key in deps) { + if (Object.prototype.hasOwnProperty.call(deps, key)) { + formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}\n`; + } + } + window.navigator.clipboard.writeText(formatted); + } +}; + +/** @public */ +export const InfoContent = () => { + const classes = useStyles(); + const { about, loading, error } = useInfo(); + + if (loading) { + return ; + } else if (error) { + return {error.message}; + } + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + copyToClipboard({ about }); + }} + className={classes.copyButton} + > + + + + + + + + + + + + ); +}; diff --git a/plugins/devtools/src/components/Content/InfoContent/InfoDependenciesTable.tsx b/plugins/devtools/src/components/Content/InfoContent/InfoDependenciesTable.tsx new file mode 100644 index 0000000000..e1ab59f279 --- /dev/null +++ b/plugins/devtools/src/components/Content/InfoContent/InfoDependenciesTable.tsx @@ -0,0 +1,55 @@ +/* + * Copyright 2022 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 { Table, TableColumn } from '@backstage/core-components'; +import { PackageDependency } from '@backstage/plugin-devtools-common'; + +import React from 'react'; + +const columns: TableColumn[] = [ + { + title: 'Name', + width: 'auto', + field: 'name', + defaultSort: 'asc', + }, + { + title: 'Versions', + width: 'auto', + field: 'versions', + }, +]; + +export const InfoDependenciesTable = ({ + infoDependencies, +}: { + infoDependencies: PackageDependency[] | undefined; +}) => { + return ( +
+ ); +}; diff --git a/plugins/devtools/src/components/Content/InfoContent/index.ts b/plugins/devtools/src/components/Content/InfoContent/index.ts new file mode 100644 index 0000000000..6d5bad53f8 --- /dev/null +++ b/plugins/devtools/src/components/Content/InfoContent/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { InfoContent } from './InfoContent'; diff --git a/plugins/devtools/src/components/Content/index.ts b/plugins/devtools/src/components/Content/index.ts new file mode 100644 index 0000000000..f5bd64f7c0 --- /dev/null +++ b/plugins/devtools/src/components/Content/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2022 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. + */ + +export * from './ConfigContent'; +export * from './InfoContent'; +export * from './ExternalDependenciesContent'; diff --git a/plugins/devtools/src/components/DefaultDevToolsPage/DefaultDevToolsPage.tsx b/plugins/devtools/src/components/DefaultDevToolsPage/DefaultDevToolsPage.tsx new file mode 100644 index 0000000000..a5e4f2439b --- /dev/null +++ b/plugins/devtools/src/components/DefaultDevToolsPage/DefaultDevToolsPage.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2022 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 { + devToolsConfigReadPermission, + devToolsInfoReadPermission, +} from '@backstage/plugin-devtools-common'; + +import { ConfigContent } from '../Content/ConfigContent'; +import { DevToolsLayout } from '../DevToolsLayout'; +import { InfoContent } from '../Content/InfoContent'; +import React from 'react'; +import { RequirePermission } from '@backstage/plugin-permission-react'; + +/** @public */ +export const DefaultDevToolsPage = () => ( + + + + + + + + + + + + +); diff --git a/plugins/devtools/src/components/DefaultDevToolsPage/index.ts b/plugins/devtools/src/components/DefaultDevToolsPage/index.ts new file mode 100644 index 0000000000..133dcf6e3a --- /dev/null +++ b/plugins/devtools/src/components/DefaultDevToolsPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { DefaultDevToolsPage } from './DefaultDevToolsPage'; diff --git a/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx new file mode 100644 index 0000000000..12cd3f7666 --- /dev/null +++ b/plugins/devtools/src/components/DevToolsLayout/DevToolsLayout.tsx @@ -0,0 +1,79 @@ +/* + * Copyright 2022 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 { Header, Page, RoutedTabs } from '@backstage/core-components'; +import { + attachComponentData, + useElementFilter, +} from '@backstage/core-plugin-api'; +import { TabProps } from '@material-ui/core'; +import { default as React } from 'react'; + +/** @public */ +export type SubRoute = { + path: string; + title: string; + children: JSX.Element; + tabProps?: TabProps; +}; + +const dataKey = 'plugin.devtools.devtoolsLayoutRoute'; + +const Route: (props: SubRoute) => null = () => null; +attachComponentData(Route, dataKey, true); + +// This causes all mount points that are discovered within this route to use the path of the route itself +attachComponentData(Route, 'core.gatherMountPoints', true); + +/** @public */ +export type DevToolsLayoutProps = { + children?: React.ReactNode; +}; + +/** + * DevTools is a compound component, which allows you to define a custom layout + * + * @example + * ```jsx + * + * + *
This is rendered under /example/anything-here route
+ *
+ *
+ * ``` + * @public + */ +export const DevToolsLayout = ({ children }: DevToolsLayoutProps) => { + const routes = useElementFilter(children, elements => + elements + .selectByComponentData({ + key: dataKey, + withStrictError: + 'Child of DevToolsLayout must be an DevToolsLayout.Route', + }) + .getElements() + .map(child => child.props), + ); + + return ( + +
+ + + ); +}; + +DevToolsLayout.Route = Route; diff --git a/plugins/devtools/src/components/DevToolsLayout/index.tsx b/plugins/devtools/src/components/DevToolsLayout/index.tsx new file mode 100644 index 0000000000..0bef371b05 --- /dev/null +++ b/plugins/devtools/src/components/DevToolsLayout/index.tsx @@ -0,0 +1,18 @@ +/* + * Copyright 2022 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. + */ + +export type { DevToolsLayoutProps, SubRoute } from './DevToolsLayout'; +export { DevToolsLayout } from './DevToolsLayout'; diff --git a/plugins/devtools/src/components/DevToolsPage/DevToolsPage.tsx b/plugins/devtools/src/components/DevToolsPage/DevToolsPage.tsx new file mode 100644 index 0000000000..880efed68c --- /dev/null +++ b/plugins/devtools/src/components/DevToolsPage/DevToolsPage.tsx @@ -0,0 +1,25 @@ +/* + * Copyright 2022 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 React from 'react'; +import { useOutlet } from 'react-router-dom'; +import { DefaultDevToolsPage } from '../DefaultDevToolsPage'; + +export const DevToolsPage = () => { + const outlet = useOutlet(); + + return <>{outlet || }; +}; diff --git a/plugins/devtools/src/components/DevToolsPage/index.ts b/plugins/devtools/src/components/DevToolsPage/index.ts new file mode 100644 index 0000000000..88d8bc06fa --- /dev/null +++ b/plugins/devtools/src/components/DevToolsPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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. + */ + +export { DevToolsPage } from './DevToolsPage'; diff --git a/plugins/devtools/src/components/index.ts b/plugins/devtools/src/components/index.ts new file mode 100644 index 0000000000..9938866bcc --- /dev/null +++ b/plugins/devtools/src/components/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 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. + */ + +export * from './Content'; +export * from './DevToolsLayout'; diff --git a/plugins/devtools/src/hooks/index.ts b/plugins/devtools/src/hooks/index.ts new file mode 100644 index 0000000000..bb2e83d06f --- /dev/null +++ b/plugins/devtools/src/hooks/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2022 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. + */ + +export { useConfig } from './useConfig'; +export { useExternalDependencies } from './useExternalDependencies'; +export { useInfo } from './useInfo'; diff --git a/plugins/devtools/src/hooks/useConfig.ts b/plugins/devtools/src/hooks/useConfig.ts new file mode 100644 index 0000000000..6703e7ea59 --- /dev/null +++ b/plugins/devtools/src/hooks/useConfig.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 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 { devToolsApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { ConfigInfo } from '@backstage/plugin-devtools-common'; + +export function useConfig(): { + configInfo?: ConfigInfo; + loading: boolean; + error?: Error; +} { + const api = useApi(devToolsApiRef); + const { value, loading, error } = useAsync(() => { + return api.getConfig(); + }, [api]); + + return { + configInfo: value, + loading, + error, + }; +} diff --git a/plugins/devtools/src/hooks/useExternalDependencies.ts b/plugins/devtools/src/hooks/useExternalDependencies.ts new file mode 100644 index 0000000000..df2f3e193b --- /dev/null +++ b/plugins/devtools/src/hooks/useExternalDependencies.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 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 { devToolsApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { ExternalDependency } from '@backstage/plugin-devtools-common'; + +export function useExternalDependencies(): { + externalDependencies?: ExternalDependency[]; + loading: boolean; + error?: Error; +} { + const api = useApi(devToolsApiRef); + const { value, loading, error } = useAsync(() => { + return api.getExternalDependencies(); + }, [api]); + + return { + externalDependencies: value, + loading, + error, + }; +} diff --git a/plugins/devtools/src/hooks/useInfo.ts b/plugins/devtools/src/hooks/useInfo.ts new file mode 100644 index 0000000000..ad700cb3fe --- /dev/null +++ b/plugins/devtools/src/hooks/useInfo.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 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 { devToolsApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { DevToolsInfo } from '@backstage/plugin-devtools-common'; + +export function useInfo(): { + about?: DevToolsInfo; + loading: boolean; + error?: Error; +} { + const api = useApi(devToolsApiRef); + const { value, loading, error } = useAsync(() => { + return api.getInfo(); + }, [api]); + + return { + about: value, + loading, + error, + }; +} diff --git a/plugins/devtools/src/index.ts b/plugins/devtools/src/index.ts new file mode 100644 index 0000000000..1077a2518c --- /dev/null +++ b/plugins/devtools/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 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. + */ + +/** + * Backstage DevTools frontend plugin with a tab that shows package dependencies and another tab that shows your current configuration. + * + * @packageDocumentation + */ + +export { devToolsPlugin, DevToolsPage } from './plugin'; +export * from './components'; diff --git a/plugins/devtools/src/plugin.test.ts b/plugins/devtools/src/plugin.test.ts new file mode 100644 index 0000000000..62f4ae5a61 --- /dev/null +++ b/plugins/devtools/src/plugin.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2022 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 { devToolsPlugin } from './plugin'; + +describe('devtools', () => { + it('should export plugin', () => { + expect(devToolsPlugin).toBeDefined(); + }); +}); diff --git a/plugins/devtools/src/plugin.ts b/plugins/devtools/src/plugin.ts new file mode 100644 index 0000000000..df2aca3447 --- /dev/null +++ b/plugins/devtools/src/plugin.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2022 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 { + createApiFactory, + createPlugin, + createRoutableExtension, + discoveryApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { devToolsApiRef, DevToolsClient } from './api'; + +import { rootRouteRef } from './routes'; + +/** @public */ +export const devToolsPlugin = createPlugin({ + id: 'devtools', + apis: [ + createApiFactory({ + api: devToolsApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new DevToolsClient({ discoveryApi, identityApi }), + }), + ], + routes: { + root: rootRouteRef, + }, +}); + +/** @public */ +export const DevToolsPage = devToolsPlugin.provide( + createRoutableExtension({ + name: 'DevToolsPage', + component: () => + import('./components/DevToolsPage').then(m => m.DevToolsPage), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/devtools/src/routes.ts b/plugins/devtools/src/routes.ts new file mode 100644 index 0000000000..7825f928be --- /dev/null +++ b/plugins/devtools/src/routes.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2022 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 { createRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'devtools', +}); diff --git a/plugins/devtools/src/setupTests.ts b/plugins/devtools/src/setupTests.ts new file mode 100644 index 0000000000..7a459ed24e --- /dev/null +++ b/plugins/devtools/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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 '@testing-library/jest-dom'; diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index 5ede228812..fe0d954772 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-dynatrace +## 5.0.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 5.0.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 5.0.0-next.1 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index b7c8244753..1546562169 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "5.0.0-next.1", + "version": "5.0.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback-backend/CHANGELOG.md b/plugins/entity-feedback-backend/CHANGELOG.md index 2ee2ffb799..82fd67a96c 100644 --- a/plugins/entity-feedback-backend/CHANGELOG.md +++ b/plugins/entity-feedback-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-entity-feedback-backend +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-entity-feedback-common@0.1.1 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index bfda97de8f..ec5a379830 100644 --- a/plugins/entity-feedback-backend/package.json +++ b/plugins/entity-feedback-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback-backend", - "version": "0.1.3-next.1", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback/CHANGELOG.md b/plugins/entity-feedback/CHANGELOG.md index 3f4575ca8a..312f6c1fd4 100644 --- a/plugins/entity-feedback/CHANGELOG.md +++ b/plugins/entity-feedback/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-entity-feedback +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-entity-feedback-common@0.1.1 + +## 0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index 0c15a0f3c8..90a9f6e4ab 100644 --- a/plugins/entity-feedback/package.json +++ b/plugins/entity-feedback/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback", - "version": "0.2.1-next.1", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-validation/CHANGELOG.md b/plugins/entity-validation/CHANGELOG.md index 9b63d46c5b..648e6fc107 100644 --- a/plugins/entity-validation/CHANGELOG.md +++ b/plugins/entity-validation/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-entity-validation +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + +## 0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index 674c5c6a56..0d375ccca9 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-validation", - "version": "0.1.3-next.1", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 9b076afbd3..4b55725420 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.2.0 + +### Minor Changes + +- 2c5661f3899: Allow endpoint configuration for sqs, enabling use of localstack for testing. + +### Patch Changes + +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-events-node@0.2.6 + +## 0.2.0-next.2 + +### Minor Changes + +- 2c5661f3899: Allow endpoint configuration for sqs, enabling use of localstack for testing. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 0125d5e5b4..e89ea4413b 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.1.7-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@aws-sdk/client-sqs": "^3.208.0", + "@aws-sdk/client-sqs": "^3.310.0", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", @@ -46,7 +46,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@aws-sdk/types": "^3.208.0", + "@aws-sdk/types": "^3.310.0", "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts index e649e2ee83..4f4e6ea55d 100644 --- a/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts +++ b/plugins/events-backend-module-aws-sqs/src/publisher/AwsSqsConsumingEventPublisher.ts @@ -68,7 +68,11 @@ export class AwsSqsConsumingEventPublisher implements EventPublisher { VisibilityTimeout: config.visibilityTimeout?.as('seconds'), WaitTimeSeconds: config.pollingWaitTime.as('seconds'), }; - this.sqs = new SQSClient({ region: config.region }); + + this.sqs = new SQSClient({ + region: config.region, + endpoint: config.endpoint, + }); this.queueUrl = config.queueUrl; this.taskTimeoutSeconds = config.timeout.as('seconds'); diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts b/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts index 1fa9df4ce3..6d7a08d7a7 100644 --- a/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts +++ b/plugins/events-backend-module-aws-sqs/src/publisher/config.test.ts @@ -79,6 +79,7 @@ describe('readConfig', () => { url: 'https://fake1.queue.url', visibilityTimeout: { minutes: 5 }, waitTime: { seconds: 10 }, + endpoint: 'https://fake.endpoint.url', }, timeout: { minutes: 5 }, waitTimeAfterEmptyReceive: { seconds: 30 }, @@ -97,6 +98,7 @@ describe('readConfig', () => { expect(publisherConfigs[0].topic).toEqual('fake1'); expect(publisherConfigs[0].region).toEqual('eu-west-1'); expect(publisherConfigs[0].queueUrl).toEqual('https://fake1.queue.url'); + expect(publisherConfigs[0].endpoint).toEqual('https://fake.endpoint.url'); expect(publisherConfigs[0].pollingWaitTime.as('seconds')).toBe(10); expect(publisherConfigs[0].timeout.as('seconds')).toBe(300); expect(publisherConfigs[0].waitTimeAfterEmptyReceive.as('seconds')).toBe( diff --git a/plugins/events-backend-module-aws-sqs/src/publisher/config.ts b/plugins/events-backend-module-aws-sqs/src/publisher/config.ts index c6b74ea8d3..eeb650ff6c 100644 --- a/plugins/events-backend-module-aws-sqs/src/publisher/config.ts +++ b/plugins/events-backend-module-aws-sqs/src/publisher/config.ts @@ -31,6 +31,7 @@ export interface AwsSqsEventSourceConfig { topic: string; visibilityTimeout?: Duration; waitTimeAfterEmptyReceive: Duration; + endpoint?: string; } // TODO(pjungermann): validation could be improved similar to `convertToHumanDuration` at @backstage/backend-tasks @@ -74,6 +75,7 @@ export function readConfig(config: Config): AwsSqsEventSourceConfig[] { } const queueUrl = topicConfig.getString('queue.url'); const region = topicConfig.getString('queue.region'); + const endpoint = topicConfig.getOptionalString('queue.endpoint'); const visibilityTimeout = readOptionalDuration( topicConfig, 'queue.visibilityTimeout', @@ -106,6 +108,7 @@ export function readConfig(config: Config): AwsSqsEventSourceConfig[] { return { pollingWaitTime, queueUrl, + endpoint, region, timeout, topic, diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index b89363b7c3..0e096953a4 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-azure +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 3667e73ebd..099da38f40 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index ea70f7686e..dc861fc027 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index ea04a4faaa..b30f50265b 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 411d9ffff8..e0e19a0899 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 64fe31d31f..e18616d98d 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 0e2b2ae8de..7f88bb5d13 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-github +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 74b74469ca..0117792b8d 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index d8d48674c8..f6827b90f4 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index 07102c0b6f..fc33203460 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 3d665a44ce..14d73356e0 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.6 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 3d46ea9210..d3340d5baf 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-backend-test-utils", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 929a003cf9..25b0561c74 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-events-backend +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-events-node@0.2.6 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index fdaee7d4a8..8d75caf02b 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.2.6-next.1", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index c44e1e3999..a8ff8ed2e5 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-events-node +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.5.2 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 7a368206bf..497d668cde 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-node", "description": "The plugin-events-node module for @backstage/plugin-events-backend", - "version": "0.2.6-next.1", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 3fb578f05a..b71a26219e 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @internal/plugin-todo-list-backend +## 1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 1.0.13-next.1 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 0b635586b7..bec7f06a4c 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.13-next.1", + "version": "1.0.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 87cc779cde..fad5737566 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,23 @@ # @internal/plugin-todo-list +## 1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 1.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 1.0.13-next.0 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index fcd193bd5f..5dff8b4a15 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.13-next.0", + "version": "1.0.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore-backend/CHANGELOG.md b/plugins/explore-backend/CHANGELOG.md index d178b091b1..a1763f7a0c 100644 --- a/plugins/explore-backend/CHANGELOG.md +++ b/plugins/explore-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-explore-backend +## 0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-search-backend-module-explore@0.1.1 + - @backstage/config@1.0.7 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.3 + ## 0.0.7-next.1 ### Patch Changes diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 7b21e885c1..538468a118 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore-backend", - "version": "0.0.7-next.1", + "version": "0.0.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 3ad9bdb917..fbfe54f16b 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-explore +## 0.4.3 + +### Patch Changes + +- 1996920782b: Make sure that the first support button row does not break across lines +- 4851581deb6: Display the title of the entity on the explore card if present, otherwise stick to the name +- a6025e25d99: Updated the example code in the "Customization" section of the README to make the imports match the components used. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.28 + - @backstage/plugin-search-common@1.2.3 + +## 0.4.3-next.2 + +### Patch Changes + +- 4851581deb6: Display the title of the entity on the explore card if present, otherwise stick to the name +- a6025e25d99: Updated the example code in the "Customization" section of the README to make the imports match the components used. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-explore-react@0.0.28 + - @backstage/core-plugin-api@1.5.1 + ## 0.4.3-next.1 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index bbe114c1f0..b0c5bf3fd9 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.4.3-next.1", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index 27c6a1b62e..4353f8e6ba 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-firehydrant +## 0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index d5e136229c..f2eda9092c 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.2.2-next.1", + "version": "0.2.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 0399ad0ce2..2ca2c69658 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-fossa +## 0.2.50 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.50-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.50-next.1 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 985202a403..caaa497130 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.50-next.1", + "version": "0.2.50", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 1c23885154..cb1f1e451b 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-gcalendar +## 0.3.14 + +### Patch Changes + +- f493ccb9589: Pass user info email scope on auth refresh to resolve invalid credentials error +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.14-next.0 ### Patch Changes diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index 0cc77cabad..eb19dd4e6f 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.14-next.0", + "version": "0.3.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gcalendar/src/hooks/useSignIn.ts b/plugins/gcalendar/src/hooks/useSignIn.ts index 351707b54e..3dbc778cf1 100644 --- a/plugins/gcalendar/src/hooks/useSignIn.ts +++ b/plugins/gcalendar/src/hooks/useSignIn.ts @@ -25,7 +25,10 @@ export const useSignIn = () => { const signIn = useCallback( async (optional = false) => { const token = await authApi.getAccessToken( - 'https://www.googleapis.com/auth/calendar.readonly', + [ + 'https://www.googleapis.com/auth/calendar.readonly', + 'https://www.googleapis.com/auth/userinfo.email', + ], { optional, instantPopup: !optional, diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 7a5ea25c0d..54265c8c59 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-gcp-projects +## 0.3.37 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.37-next.0 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 039bcd094c..6d320cad6d 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.37-next.0", + "version": "0.3.37", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index 976585c656..80f09319d0 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-git-release-manager +## 0.3.31 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.31-next.1 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 7bc4df059e..76d18dc224 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.31-next.1", + "version": "0.3.31", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 09b205c9f1..199051dd04 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-github-actions +## 0.5.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.5.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.5.18-next.1 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 25fac2b774..98a558cd0d 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.5.18-next.1", + "version": "0.5.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 41475febd3..0a699bdc57 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-github-deployments +## 0.1.49 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.49-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.49-next.1 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index dcb4156f9d..08c7e1aa9d 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.49-next.1", + "version": "0.1.49", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index d1e2103800..6f83ae81cf 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-github-issues +## 0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.7-next.1 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index ed982410e9..c6685eff13 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.7-next.1", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index 7421c6e015..704dc495c1 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.12 + +### Patch Changes + +- cf125c36569: The `EntityTeamPullRequestsContent` and `EntityTeamPullRequestsCard` support the ability to view the labels/tags added to each PR +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index e805cd99ce..da3c929b43 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.12-next.1", + "version": "0.1.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 99122116fb..4aed3f9ab3 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-gitops-profiles +## 0.3.36 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.36-next.0 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 2bb6f145a4..e374b49335 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.36-next.0", + "version": "0.3.36", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 14a0149ca5..0014eebd8c 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-gocd +## 0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.24-next.1 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index 2e41e2c217..11ee841aa2 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.24-next.1", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index e831845d49..5f395bda29 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-graphiql +## 0.2.50 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.50-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.50-next.0 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 08fc2a6ec0..d5dae8c2ec 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.50-next.0", + "version": "0.2.50", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 898e185d5d..14f2b75eac 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-graphql-backend +## 0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-graphql@0.3.20 + ## 0.1.35-next.1 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 388b587040..cc8c3e3059 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.35-next.1", + "version": "0.1.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/graphql-voyager/CHANGELOG.md b/plugins/graphql-voyager/CHANGELOG.md index 77586073af..394b99f5c7 100644 --- a/plugins/graphql-voyager/CHANGELOG.md +++ b/plugins/graphql-voyager/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-graphql-voyager +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/graphql-voyager/package.json b/plugins/graphql-voyager/package.json index d356dee1c5..683b664b33 100644 --- a/plugins/graphql-voyager/package.json +++ b/plugins/graphql-voyager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-voyager", "description": "Backstage plugin for GraphQL Voyager", - "version": "0.1.3-next.0", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 868b1a6c3b..b626f5c5e6 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-home +## 0.5.2 + +### Patch Changes + +- acca8966465: Remove object-hash dependency +- 957cd9b8958: Use the semantic time tag for rendering world clocks on homepage headers. +- 0e19e7b0f3a: Bump to using the later v5 versions of `@rjsf/*` +- 5272cfabc3b: Add missing @rjsf/core dependency +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.5.2-next.2 + +### Patch Changes + +- acca8966465: Remove object-hash dependency +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.5.2-next.1 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index ef9267234b..ff714b16ca 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.5.2-next.1", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -48,7 +48,6 @@ "@rjsf/validator-ajv8": "5.6.0", "@types/react": "^16.13.1 || ^17.0.0", "lodash": "^4.17.21", - "object-hash": "^3.0.0", "react-grid-layout": "^1.3.4", "react-resizable": "^3.0.4", "react-use": "^17.2.4", diff --git a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx index 232fbd12c2..6af9044cbd 100644 --- a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx +++ b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx @@ -46,7 +46,6 @@ import { CardConfig } from '../../extensions'; // eslint-disable-next-line new-cap const ResponsiveGrid = WidthProvider(Responsive); -const hash = require('object-hash'); const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -336,14 +335,14 @@ export const CustomHomepageGrid = (props: CustomHomepageGridProps) => { ...widget.component.props, ...(w.settings ?? {}), }; - const propsHash = hash(widgetProps, {}); + return (
- + {editMode && ( { />, ); - expect(rendered.getByText('09:10')).toBeInTheDocument(); + expect(rendered.getByText('09:10')).toHaveAttribute('datetime', '09:10'); }); }); diff --git a/plugins/home/src/homePageComponents/HeaderWorldClock/HeaderWorldClock.tsx b/plugins/home/src/homePageComponents/HeaderWorldClock/HeaderWorldClock.tsx index a45a51e0ad..394af1a27b 100644 --- a/plugins/home/src/homePageComponents/HeaderWorldClock/HeaderWorldClock.tsx +++ b/plugins/home/src/homePageComponents/HeaderWorldClock/HeaderWorldClock.tsx @@ -23,8 +23,9 @@ const timeFormat: Intl.DateTimeFormatOptions = { }; type TimeObj = { - time: string; label: string; + value: string; + dateTime: string; }; /** @public */ @@ -65,8 +66,14 @@ function getTimes( label = 'GMT'; } - const time = d.toLocaleTimeString(lang, options); - clocks.push({ time, label }); + const value = d.toLocaleTimeString(lang, options); + const dateTime = d.toLocaleTimeString(lang, { + timeZone: options.timeZone, + hour: '2-digit', + minute: '2-digit', + hour12: false, + }); + clocks.push({ label, value, dateTime }); } return clocks; @@ -129,9 +136,9 @@ export const HeaderWorldClock = (props: { <> {clocks.map(clock => ( {clock.value}} /> ))} diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 0f5b044bfb..0b1c5b5696 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-ilert +## 0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.7-next.1 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 17e94d54e5..396d5f6860 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.2.7-next.1", + "version": "0.2.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 8e4463f46b..6bb9cba867 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-jenkins-backend +## 0.2.0 + +### Minor Changes + +- cf95c5137c9: Updated rebuild to use Jenkins API replay build, which works for Jenkins jobs that have required parameters. Jenkins SDK could not be used for this request because it does not have support for replay. + + Added link to view build in Jenkins CI/CD table action column. + +### Patch Changes + +- 670a2dd6f4e: Fix handling of slashes in branch names +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-jenkins-common@0.1.15 + - @backstage/plugin-permission-common@0.7.5 + ## 0.1.35-next.1 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index 4f58776df7..f45908c04e 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.35-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -36,6 +36,7 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "jenkins": "^1.0.0", + "node-fetch": "^2.6.7", "winston": "^3.2.1", "yn": "^4.0.0" }, diff --git a/plugins/jenkins-backend/src/service/jenkinsApi.test.ts b/plugins/jenkins-backend/src/service/jenkinsApi.test.ts index c89a3866c7..8e80de34a3 100644 --- a/plugins/jenkins-backend/src/service/jenkinsApi.test.ts +++ b/plugins/jenkins-backend/src/service/jenkinsApi.test.ts @@ -19,9 +19,10 @@ import jenkins from 'jenkins'; import { JenkinsInfo } from './jenkinsInfoProvider'; import { JenkinsBuild, JenkinsProject } from '../types'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; -import { NotAllowedError } from '@backstage/errors'; +import fetch, { Response } from 'node-fetch'; jest.mock('jenkins'); +jest.mock('node-fetch'); const mockedJenkinsClient = { job: { get: jest.fn(), @@ -54,6 +55,11 @@ const fakePermissionApi = { describe('JenkinsApi', () => { const jenkinsApi = new JenkinsApiImpl(fakePermissionApi); + const mockFetch = fetch as jest.MockedFunction; + + afterEach(() => { + jest.clearAllMocks(); + }); describe('getProjects', () => { const project: JenkinsProject = { @@ -689,55 +695,63 @@ describe('JenkinsApi', () => { buildNumber, ); }); - it('buildProject', async () => { - await jenkinsApi.buildProject(jenkinsInfo, jobFullName, resourceRef); + it('getBuildUrl', async () => { + const jenkinsApiProto = Object.getPrototypeOf(jenkinsApi); + const buildUrl = jenkinsApiProto.getBuildUrl( + jenkinsInfo, + jobFullName, + buildNumber, + ); + expect(buildUrl).toEqual( + 'https://jenkins.example.com/job/example-jobName/job/foo/19', + ); - expect(mockedJenkins).toHaveBeenCalledWith({ - baseUrl: jenkinsInfo.baseUrl, - headers: jenkinsInfo.headers, - promisify: true, - }); - expect(mockedJenkinsClient.job.build).toHaveBeenCalledWith(jobFullName); + const buildUrlTriple = jenkinsApiProto.getBuildUrl( + jenkinsInfo, + 'example-jobName/foo/bar', + buildNumber, + ); + expect(buildUrlTriple).toEqual( + 'https://jenkins.example.com/job/example-jobName/job/foo/job/bar/19', + ); }); - - it('buildProject should fail if it does not have required permissions', async () => { - fakePermissionApi.authorize.mockResolvedValueOnce([ - { - result: AuthorizeResult.DENY, - }, - ]); - - await expect(() => - jenkinsApi.buildProject(jenkinsInfo, jobFullName, resourceRef), - ).rejects.toThrow(NotAllowedError); - }); - - it('buildProject should succeed if it have required permissions', async () => { - fakePermissionApi.authorize.mockResolvedValueOnce([ - { - result: AuthorizeResult.ALLOW, - }, - ]); - - await jenkinsApi.buildProject(jenkinsInfo, jobFullName, resourceRef); - expect(mockedJenkins).toHaveBeenCalledWith({ - baseUrl: jenkinsInfo.baseUrl, - headers: jenkinsInfo.headers, - promisify: true, + describe('rebuildProject', () => { + it('successfully rebuilds', async () => { + mockFetch.mockResolvedValueOnce({ status: 200 } as Response); + const status = await jenkinsApi.rebuildProject( + jenkinsInfo, + jobFullName, + buildNumber, + resourceRef, + ); + expect(status).toEqual(200); }); - expect(mockedJenkinsClient.job.build).toHaveBeenCalledWith(jobFullName); - }); - - it('buildProject with crumbIssuer option', async () => { - const info: JenkinsInfo = { ...jenkinsInfo, crumbIssuer: true }; - await jenkinsApi.buildProject(info, jobFullName, resourceRef); - - expect(mockedJenkins).toHaveBeenCalledWith({ - baseUrl: jenkinsInfo.baseUrl, - headers: jenkinsInfo.headers, - promisify: true, - crumbIssuer: true, + it('fails to rebuild', async () => { + mockFetch.mockResolvedValueOnce({ status: 401 } as Response); + const status = await jenkinsApi.rebuildProject( + jenkinsInfo, + jobFullName, + buildNumber, + resourceRef, + ); + expect(status).toEqual(401); + }); + + it('should fail if it does not have required permissions', async () => { + fakePermissionApi.authorize.mockResolvedValueOnce([ + { + result: AuthorizeResult.DENY, + }, + ]); + + mockFetch.mockResolvedValueOnce({ status: 200 } as Response); + const status = await jenkinsApi.rebuildProject( + jenkinsInfo, + jobFullName, + buildNumber, + resourceRef, + ); + expect(status).toEqual(401); }); - expect(mockedJenkinsClient.job.build).toHaveBeenCalledWith(jobFullName); }); }); diff --git a/plugins/jenkins-backend/src/service/jenkinsApi.ts b/plugins/jenkins-backend/src/service/jenkinsApi.ts index e14437fa68..85271462eb 100644 --- a/plugins/jenkins-backend/src/service/jenkinsApi.ts +++ b/plugins/jenkins-backend/src/service/jenkinsApi.ts @@ -28,7 +28,7 @@ import { PermissionEvaluator, } from '@backstage/plugin-permission-common'; import { jenkinsExecutePermission } from '@backstage/plugin-jenkins-common'; -import { NotAllowedError } from '@backstage/errors'; +import fetch, { HeaderInit } from 'node-fetch'; export class JenkinsApiImpl { private static readonly lastBuildTreeSpec = `lastBuild[ @@ -144,14 +144,13 @@ export class JenkinsApiImpl { * Trigger a build of a project * @see ../../../jenkins/src/api/JenkinsApi.ts#retry */ - async buildProject( + async rebuildProject( jenkinsInfo: JenkinsInfo, jobFullName: string, + buildNumber: number, resourceRef: string, options?: { token?: string }, - ) { - const client = await JenkinsApiImpl.getClient(jenkinsInfo); - + ): Promise { if (this.permissionApi) { const response = await this.permissionApi.authorize( [{ permission: jenkinsExecutePermission, resourceRef }], @@ -160,16 +159,19 @@ export class JenkinsApiImpl { // permission api returns always at least one item, we need to check only one result since we do not expect any additional results const { result } = response[0]; if (result === AuthorizeResult.DENY) { - throw new NotAllowedError(); + return 401; } } - // looks like the current SDK only supports triggering a new build - // can't see any support for replay (re-running the specific build with the same SCM info) + const buildUrl = this.getBuildUrl(jenkinsInfo, jobFullName, buildNumber); - // Note Jenkins itself has concepts of rebuild and replay on a job. - // The latter should be possible to trigger with a POST to /replay/rebuild - await client.job.build(jobFullName); + // the current SDK only supports triggering a new build + // replay the job by triggering request directly from Jenkins api + const response = await fetch(`${buildUrl}/replay/rebuild`, { + method: 'post', + headers: jenkinsInfo.headers as HeaderInit, + }); + return response.status; } // private helper methods @@ -318,4 +320,13 @@ export class JenkinsApiImpl { }) .pop(); } + + private getBuildUrl( + jenkinsInfo: JenkinsInfo, + jobFullName: string, + buildId: number, + ): string { + const jobs = jobFullName.split('/'); + return `${jenkinsInfo.baseUrl}/job/${jobs.join('/job/')}/${buildId}`; + } } diff --git a/plugins/jenkins-backend/src/service/router.ts b/plugins/jenkins-backend/src/service/router.ts index df4c3b5a11..484bfa273f 100644 --- a/plugins/jenkins-backend/src/service/router.ts +++ b/plugins/jenkins-backend/src/service/router.ts @@ -145,9 +145,10 @@ export async function createRouter( ); router.post( - '/v1/entity/:namespace/:kind/:name/job/:jobFullName/:buildNumber::rebuild', + '/v1/entity/:namespace/:kind/:name/job/:jobFullName/:buildNumber', async (request, response) => { - const { namespace, kind, name, jobFullName } = request.params; + const { namespace, kind, name, jobFullName, buildNumber } = + request.params; const token = getBearerTokenFromAuthorizationHeader( request.header('authorization'), ); @@ -162,10 +163,16 @@ export async function createRouter( }); const resourceRef = stringifyEntityRef({ kind, namespace, name }); - await jenkinsApi.buildProject(jenkinsInfo, jobFullName, resourceRef, { - token, - }); - response.json({}); + const status = await jenkinsApi.rebuildProject( + jenkinsInfo, + jobFullName, + parseInt(buildNumber, 10), + resourceRef, + { + token, + }, + ); + response.json({}).status(status); }, ); router.use(errorHandler()); diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 6b900dcb18..1b289faef2 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-jenkins +## 0.8.0 + +### Minor Changes + +- cf95c5137c9: Updated rebuild to use Jenkins API replay build, which works for Jenkins jobs that have required parameters. Jenkins SDK could not be used for this request because it does not have support for replay. + + Added link to view build in Jenkins CI/CD table action column. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-jenkins-common@0.1.15 + +## 0.7.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.7.17-next.1 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index e57c1c77f2..1f980215c2 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.7.17-next.1", + "version": "0.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins/src/assets/folder-results.png b/plugins/jenkins/src/assets/folder-results.png index 2c14d5d927..340b03549d 100644 Binary files a/plugins/jenkins/src/assets/folder-results.png and b/plugins/jenkins/src/assets/folder-results.png differ diff --git a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx index 1bb6dbaefc..f2d108eaf7 100644 --- a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx +++ b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx @@ -18,6 +18,7 @@ import { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { useEntityPermission } from '@backstage/plugin-catalog-react/alpha'; import { Box, IconButton, Tooltip, Typography } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; +import VisibilityIcon from '@material-ui/icons/Visibility'; import { default as React, useState } from 'react'; import { Project } from '../../../../api/JenkinsApi'; import JenkinsLogo from '../../../../assets/JenkinsLogo.svg'; @@ -203,16 +204,23 @@ const generatedColumns: TableColumn[] = [ }; return ( - - <> - {isLoadingRebuild && } - {!isLoadingRebuild && ( +
+ {row.lastBuild?.url && ( + + + + + + )} + {isLoadingRebuild && } + {!isLoadingRebuild && ( + - )} - - + + )} +
); }; return ; diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 2b788a1bea..3620351d77 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-kafka-backend +## 0.2.38 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.2.38-next.1 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 7eb51bfe72..584dcfe8a2 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.2.38-next.1", + "version": "0.2.38", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 42f46a13a7..fd41b779a6 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-kafka +## 0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index c4eebb6446..0baee01c27 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.18-next.1", + "version": "0.3.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index fd6a844304..3ede951ab9 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-kubernetes-backend +## 0.11.0 + +### Minor Changes + +- f4114f02d49: Allow fetching pod metrics limited by a `labelSelector`. + + This is used by the Kubernetes tab on a components' page and leads to much smaller responses being received from Kubernetes, especially with larger Kubernetes clusters. + +- 890988341e9: Update `aws-sdk` client from v2 to v3. + + **BREAKING**: The `AwsIamKubernetesAuthTranslator` class no longer exposes the following methods `awsGetCredentials`, `getBearerToken`, `getCredentials` and `validCredentials`. There is no replacement for these methods. + +### Patch Changes + +- 05f1d74539d: Kubernetes clusters now support `authProvider: aks`. When configured this way, + the `retrieveObjectsByServiceId` action will use the `auth.aks` value in the + request body as a bearer token to authenticate with Kubernetes. +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- a341129b754: Fixed a bug in the Kubernetes proxy endpoint where requests to clusters configured with client-side auth providers would always fail with a 500 status. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + +## 0.11.0-next.2 + +### Patch Changes + +- 05f1d74539d: Kubernetes clusters now support `authProvider: aks`. When configured this way, + the `retrieveObjectsByServiceId` action will use the `auth.aks` value in the + request body as a bearer token to authenticate with Kubernetes. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/config@1.0.7 + - @backstage/integration-aws-node@0.1.2 + ## 0.11.0-next.1 ### Minor Changes diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 668061cd31..ad8ff32891 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -21,6 +21,15 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import type { RequestHandler } from 'express'; import { TokenCredential } from '@azure/identity'; +// @public (undocumented) +export class AksKubernetesAuthTranslator { + // (undocumented) + decorateClusterDetailsWithAuth( + clusterDetails: ClusterDetails, + auth: KubernetesRequestAuth, + ): Promise; +} + // @public (undocumented) export interface AWSClusterDetails extends ClusterDetails { // (undocumented) diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 5e254f48e0..7369e54041 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.11.0-next.1", + "version": "0.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -50,7 +50,7 @@ }, "dependencies": { "@aws-crypto/sha256-js": "^3.0.0", - "@aws-sdk/credential-providers": "^3.208.0", + "@aws-sdk/credential-providers": "^3.310.0", "@aws-sdk/signature-v4": "^3.310.0", "@azure/identity": "^2.0.4", "@backstage/backend-common": "workspace:^", @@ -70,7 +70,6 @@ "@kubernetes/client-node": "0.18.1", "@types/express": "^4.17.6", "@types/luxon": "^3.0.0", - "aws4": "^1.11.0", "compression": "^1.7.4", "cors": "^2.8.5", "express": "^4.17.1", diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts index 5d8fefc5d2..7f545a95de 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.test.ts @@ -256,4 +256,19 @@ describe('ConfigClusterLocator', () => { }, ]); }); + + it('supports aks authProvider', async () => { + const cluster = { + name: 'aks-cluster', + url: 'https://aks.test', + authProvider: 'aks', + }; + const sut = ConfigClusterLocator.fromConfig( + new ConfigReader({ clusters: [cluster] }), + ); + + const result = await sut.getClusters(); + + expect(result).toMatchObject([cluster]); + }); }); diff --git a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts index b0143c2010..a759cb4bb0 100644 --- a/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts +++ b/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts @@ -76,6 +76,9 @@ export class ConfigClusterLocator implements KubernetesClustersSupplier { case 'googleServiceAccount': { return clusterDetails; } + case 'aks': { + return clusterDetails; + } default: { throw new Error( `authProvider "${authProvider}" has no config associated with it`, diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.test.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.test.ts similarity index 56% rename from plugins/linguist-backend/src/api/LinguistBackendApi.test.ts rename to plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.test.ts index 741d52e734..d0d3cf87bb 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendApi.test.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.test.ts @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { kindOrDefault } from './LinguistBackendApi'; +import { AksKubernetesAuthTranslator } from './AksKubernetesAuthTranslator'; -describe('kindOrDefault', () => { - it('should return default kind when undefined', () => { - expect(kindOrDefault()).toEqual(['API', 'Component', 'Template']); - }); - it('should return the default kind when empty', () => { - expect(kindOrDefault([])).toEqual(['API', 'Component', 'Template']); - }); - it('should return provided kind when not empty', () => { - expect(kindOrDefault(['API'])).toEqual(['API']); +describe('AksKubernetesAuthTranslator', () => { + it('uses auth.aks value as bearer token', async () => { + const translator = new AksKubernetesAuthTranslator(); + + const details = await translator.decorateClusterDetailsWithAuth( + { name: '', authProvider: 'aks', url: '' }, + { aks: 'aksToken' }, + ); + + expect(details.serviceAccountToken).toBe('aksToken'); }); }); diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.ts new file mode 100644 index 0000000000..13d784293e --- /dev/null +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AksKubernetesAuthTranslator.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 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 { ClusterDetails } from '../types/types'; +import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; + +/** + * + * @public + */ +export class AksKubernetesAuthTranslator { + async decorateClusterDetailsWithAuth( + clusterDetails: ClusterDetails, + auth: KubernetesRequestAuth, + ): Promise { + return { ...clusterDetails, serviceAccountToken: auth.aks }; + } +} diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts index 4ee83b0da0..71dcedfee6 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +export * from './AksKubernetesAuthTranslator'; export * from './AwsIamKubernetesAuthTranslator'; export * from './AzureIdentityKubernetesAuthTranslator'; export * from './GoogleKubernetesAuthTranslator'; diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 75b619b412..8f9d0769ed 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -33,6 +33,7 @@ import { GoogleServiceAccountAuthTranslator, AzureIdentityKubernetesAuthTranslator, OidcKubernetesAuthTranslator, + AksKubernetesAuthTranslator, } from '../kubernetes-auth-translator'; import { addResourceRoutesToRouter } from '../routes/resourcesRoutes'; @@ -355,6 +356,7 @@ export class KubernetesBuilder { protected buildAuthTranslatorMap() { this.authTranslatorMap = { google: new GoogleKubernetesAuthTranslator(), + aks: new AksKubernetesAuthTranslator(), aws: new AwsIamKubernetesAuthTranslator({ config: this.env.config }), azure: new AzureIdentityKubernetesAuthTranslator(this.env.logger), serviceAccount: new NoopKubernetesAuthTranslator(), diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 57eb29f0a7..97a0daa074 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -15,7 +15,7 @@ */ import 'buffer'; -import { getVoidLogger } from '@backstage/backend-common'; +import { errorHandler, getVoidLogger } from '@backstage/backend-common'; import { NotFoundError } from '@backstage/errors'; import { getMockReq, getMockRes } from '@jest-mock/express'; import type { Request } from 'express'; @@ -35,7 +35,12 @@ import { AuthorizeResult, PermissionEvaluator, } from '@backstage/plugin-permission-common'; -import { KubernetesAuthTranslator } from '../kubernetes-auth-translator'; +import { + KubernetesAuthTranslator, + NoopKubernetesAuthTranslator, +} from '../kubernetes-auth-translator'; +import Router from 'express-promise-router'; +import { LocalKubectlProxyClusterLocator } from '../cluster-locator/LocalKubectlProxyLocator'; describe('KubernetesProxy', () => { let proxy: KubernetesProxy; @@ -131,10 +136,9 @@ describe('KubernetesProxy', () => { authProvider: 'serviceAccount', } as ClusterDetails); - const app = express().use( - '/mountpath', - proxy.createRequestHandler({ permissionApi }), - ); + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); const requestPromise = request(app) .get('/mountpath/api') .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); @@ -151,7 +155,7 @@ describe('KubernetesProxy', () => { expect(response.body).toStrictEqual(apiResponse); }); - it('should default to using a provided authorization header', async () => { + it('should default to using a authTranslator provided serviceAccountToken as authorization headers to kubeapi when backstage-kubernetes-auth field is not provided', async () => { worker.use( rest.get( 'https://localhost:9999/api/v1/namespaces', @@ -160,7 +164,10 @@ describe('KubernetesProxy', () => { return res(ctx.status(401)); } - if (req.headers.get('Authorization') !== 'my-token') { + if ( + req.headers.get('Authorization') !== + 'Bearer translator-provided-token' + ) { return res(ctx.status(403)); } @@ -192,18 +199,17 @@ describe('KubernetesProxy', () => { authTranslator.decorateClusterDetailsWithAuth.mockResolvedValue({ name: 'cluster1', url: 'https://localhost:9999', - serviceAccountToken: 'random-token', + serviceAccountToken: 'translator-provided-token', authProvider: 'serviceAccount', } as ClusterDetails); - const app = express().use( - '/mountpath', - proxy.createRequestHandler({ permissionApi }), - ); + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); + const requestPromise = request(app) .get('/mountpath/api/v1/namespaces') - .set(HEADER_KUBERNETES_CLUSTER, 'cluster1') - .set('Authorization', 'my-token'); + .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); @@ -212,7 +218,7 @@ describe('KubernetesProxy', () => { expect(response.status).toEqual(200); }); - it('should add a serviceAccountToken to the request headers if one isnt provided in request and one isnt set up in cluster details', async () => { + it('should add a authTranslator provided serviceAccountToken as authorization headers to kubeapi if one isnt provided in request and one isnt set up in cluster details', async () => { worker.use( rest.get('https://localhost:9999/api/v1/namespaces', (req, res, ctx) => { if (!req.headers.get('Authorization')) { @@ -253,10 +259,10 @@ describe('KubernetesProxy', () => { authProvider: 'googleServiceAccount', } as ClusterDetails); - const app = express().use( - '/mountpath', - proxy.createRequestHandler({ permissionApi }), - ); + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); + const requestPromise = request(app) .get('/mountpath/api/v1/namespaces') .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); @@ -314,10 +320,10 @@ describe('KubernetesProxy', () => { authProvider: 'googleServiceAccount', } as ClusterDetails); - const app = express().use( - '/mountpath', - proxy.createRequestHandler({ permissionApi }), - ); + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); + const requestPromise = request(app) .get('/mountpath/api/v1/namespaces') .set(HEADER_KUBERNETES_CLUSTER, 'cluster1') @@ -334,4 +340,210 @@ describe('KubernetesProxy', () => { items: [], }); }); + + it('should not invoke authTranslator if Backstage-Kubernetes-Authorization field is provided', async () => { + worker.use( + rest.get('https://localhost:9999/api/v1/namespaces', (req, res, ctx) => { + if (!req.headers.get('Authorization')) { + return res(ctx.status(401)); + } + + if (req.headers.get('Authorization') !== 'tokenB') { + return res(ctx.status(403)); + } + + return res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); + }), + ); + + permissionApi.authorize.mockReturnValue( + Promise.resolve([{ result: AuthorizeResult.ALLOW }]), + ); + + clusterSupplier.getClusters.mockResolvedValue([ + { + name: 'cluster1', + url: 'https://localhost:9999', + authProvider: 'googleServiceAccount', + }, + ] as ClusterDetails[]); + + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); + + const requestPromise = request(app) + .get('/mountpath/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'cluster1') + .set(HEADER_KUBERNETES_AUTH, 'tokenB'); + + worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); + + const response = await requestPromise; + + expect(authTranslator.decorateClusterDetailsWithAuth).toHaveBeenCalledTimes( + 0, + ); + expect(response.status).toEqual(200); + expect(response.body).toStrictEqual({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }); + }); + + it('returns a response with a localKubectlProxy auth provider configuration', async () => { + proxy = new KubernetesProxy({ + logger: getVoidLogger(), + clusterSupplier: new LocalKubectlProxyClusterLocator(), + authTranslator: new NoopKubernetesAuthTranslator(), + }); + + worker.use( + rest.get('http://localhost:8001/api/v1/namespaces', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); + }), + ); + + permissionApi.authorize.mockReturnValue( + Promise.resolve([{ result: AuthorizeResult.ALLOW }]), + ); + + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + const app = express().use(router); + + const requestPromise = request(app) + .get('/mountpath/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'local'); + + worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); + + const response = await requestPromise; + + expect(response.status).toEqual(200); + expect(response.body).toStrictEqual({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }); + }); + + it('should return a 400 error if Backstage-Kubernetes-Cluster field isnt provided in request', async () => { + worker.use( + rest.get('https://localhost:9999/api/v1/namespaces', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); + }), + ); + + permissionApi.authorize.mockReturnValue( + Promise.resolve([{ result: AuthorizeResult.ALLOW }]), + ); + + clusterSupplier.getClusters.mockResolvedValue([ + { + name: 'cluster1', + url: 'https://localhost:9999', + authProvider: 'googleServiceAccount', + }, + ] as ClusterDetails[]); + + authTranslator.decorateClusterDetailsWithAuth.mockResolvedValue({ + name: 'cluster1', + url: 'https://localhost:9999', + serviceAccountToken: 'tokenA', + authProvider: 'googleServiceAccount', + } as ClusterDetails); + + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + router.use(errorHandler()); + const app = express().use(router); + + const requestPromise = request(app) + .get('/mountpath/api/v1/namespaces') + .set(HEADER_KUBERNETES_AUTH, 'tokenB'); + + worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); + + const response = await requestPromise; + + expect(response.status).toEqual(400); + }); + + it('returns a 500 error if authTranslator errors out and Backstage-Kubernetes-Authorization field is not provided', async () => { + worker.use( + rest.get('https://localhost:9999/api/v1/namespaces', (req, res, ctx) => { + if (!req.headers.get('Authorization')) { + return res(ctx.status(401)); + } + + if (req.headers.get('Authorization') !== 'tokenB') { + return res(ctx.status(403)); + } + + return res( + ctx.status(200), + ctx.json({ + kind: 'NamespaceList', + apiVersion: 'v1', + items: [], + }), + ); + }), + ); + + permissionApi.authorize.mockResolvedValue([ + { result: AuthorizeResult.ALLOW }, + ]); + + clusterSupplier.getClusters.mockResolvedValue([ + { + name: 'cluster1', + url: 'https://localhost:9999', + authProvider: 'google', + serviceAccountToken: 'client-side-token', + }, + ] as ClusterDetails[]); + + authTranslator.decorateClusterDetailsWithAuth.mockRejectedValue( + Error('some internal error'), + ); + + const router = Router(); + router.use('/mountpath', proxy.createRequestHandler({ permissionApi })); + router.use(errorHandler()); + const app = express().use(router); + + const requestPromise = request(app) + .get('/mountpath/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); + + worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); + + const response = await requestPromise; + + expect(response.status).toEqual(500); + }); }); diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index eb6748ffba..1a705feb84 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -98,26 +98,29 @@ export class KubernetesProxy { req.header('authorization'), ); - const authorizeResponse = ( - await permissionApi.authorize( - [{ permission: kubernetesProxyPermission }], - { - token, - }, - ) - )[0]; + const authorizeResponse = await permissionApi.authorize( + [{ permission: kubernetesProxyPermission }], + { + token, + }, + ); + const auth = authorizeResponse[0]; - if (authorizeResponse.result === AuthorizeResult.DENY) { + if (auth.result === AuthorizeResult.DENY) { res.status(403).json({ error: new NotAllowedError('Unauthorized') }); return; } - const cluster = await this.getClusterForRequest(req).then(cd => - this.authTranslator.decorateClusterDetailsWithAuth(cd, {}), - ); - if (!req.headers.authorization) { - req.headers.authorization = `Bearer ${cluster.serviceAccountToken}`; - } + req.headers.authorization = + req.header(HEADER_KUBERNETES_AUTH) ?? + `Bearer ${ + ( + await this.getClusterForRequest(req).then(cd => + this.authTranslator.decorateClusterDetailsWithAuth(cd, {}), + ) + ).serviceAccountToken + }`; + const middleware = await this.getMiddleware(req); middleware(req, res, next); }; @@ -163,13 +166,6 @@ export class KubernetesProxy { }; res.status(500).json(body); }, - onProxyReq: (proxyReq, req) => { - // the kubernetes proxy endpoint expects a header field labeled `Backstage-Kubernetes-Authorization` that will be used to authenticate with the Kubernetes Api. The token provided as a value should be an bearer token for the target cluster. - if (req.header(HEADER_KUBERNETES_AUTH)) { - const token = req.header(HEADER_KUBERNETES_AUTH) ?? ''; - proxyReq.setHeader('Authorization', token); - } - }, }); this.middlewareForClusterName.set(originalCluster.name, middleware); } diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index 520b9ed3ee..dd96cecbcf 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-kubernetes-common +## 0.6.3 + +### Patch Changes + +- 05f1d74539d: AKS access tokens can now be sent over the wire to the Kubernetes backend. +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/plugin-permission-common@0.7.5 + +## 0.6.3-next.0 + +### Patch Changes + +- 05f1d74539d: AKS access tokens can now be sent over the wire to the Kubernetes backend. + ## 0.6.2 ### Patch Changes diff --git a/plugins/kubernetes-common/api-report.md b/plugins/kubernetes-common/api-report.md index 6c88074e50..56faeea7d9 100644 --- a/plugins/kubernetes-common/api-report.md +++ b/plugins/kubernetes-common/api-report.md @@ -226,6 +226,8 @@ export const kubernetesProxyPermission: BasicPermission; // @public (undocumented) export interface KubernetesRequestAuth { + // (undocumented) + aks?: string; // (undocumented) google?: string; // (undocumented) diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 7b0cdad9c0..b3dff229d4 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.6.2", + "version": "0.6.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes-common/src/types.ts b/plugins/kubernetes-common/src/types.ts index f5701d49fe..8eabb16d24 100644 --- a/plugins/kubernetes-common/src/types.ts +++ b/plugins/kubernetes-common/src/types.ts @@ -35,6 +35,7 @@ import { Entity } from '@backstage/catalog-model'; /** @public */ export interface KubernetesRequestAuth { google?: string; + aks?: string; oidc?: { [key: string]: string; }; diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index a012240830..0f324ef8f0 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/plugin-kubernetes +## 0.9.0 + +### Minor Changes + +- 280ec10c18e: Added Pod logs components for Kubernetes plugin + + **BREAKING**: `kubernetesProxyApi` for custom plugins built with components from the Kubernetes plugin apis, `kubernetesProxyApi` should be added to the plugin's API list. + + ``` + ... + export const kubernetesPlugin = createPlugin({ + id: 'kubernetes', + apis: [ + ... + createApiFactory({ + api: kubernetesProxyApiRef, + deps: { + kubernetesApi: kubernetesApiRef, + }, + factory: ({ kubernetesApi }) => + new KubernetesProxyClient({ + kubernetesApi, + }), + }), + ``` + + **BREAKING**: `KubernetesDrawer` is now called `KubernetesStructuredMetadataTableDrawer` so that we can do more than just show `StructuredMetadataTable` + + `import { KubernetesDrawer } from "@backstage/plugin-kubernetes"` + + should now be: + + `import { KubernetesStructuredMetadataTableDrawer } from "@backstage/plugin-kubernetes"` + +### Patch Changes + +- c7bad1005ba: The Kubernetes plugin now requests AKS access tokens from Azure when retrieving + objects from clusters configured with `authProvider: aks` and sets `auth.aks` in + its request bodies appropriately. +- a160e02c3d7: Omit managed fields in the Kubernetes resource YAML display. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/plugin-kubernetes-common@0.6.3 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.9.0-next.2 + +### Patch Changes + +- c7bad1005ba: The Kubernetes plugin now requests AKS access tokens from Azure when retrieving + objects from clusters configured with `authProvider: aks` and sets `auth.aks` in + its request bodies appropriately. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-kubernetes-common@0.6.3-next.0 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.9.0-next.1 ### Minor Changes diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 60f5d3fc99..5529b7910f 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -281,6 +281,7 @@ export const kubernetesApiRef: ApiRef; // @public (undocumented) export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { constructor(options: { + microsoftAuthApi: OAuthApi; googleAuthApi: OAuthApi; oidcProviders?: { [key: string]: OpenIdConnectApi; diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 75b51cdbb5..e6a0b518a1 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.9.0-next.1", + "version": "0.9.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts b/plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts new file mode 100644 index 0000000000..401fc1e127 --- /dev/null +++ b/plugins/kubernetes/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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 { OAuthApi } from '@backstage/core-plugin-api'; +import { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common'; +import { KubernetesAuthProvider } from './types'; + +export class AksKubernetesAuthProvider implements KubernetesAuthProvider { + constructor(private readonly microsoftAuthApi: OAuthApi) {} + + async decorateRequestBodyForAuth( + requestBody: KubernetesRequestBody, + ): Promise { + return { + ...requestBody, + auth: { ...requestBody.auth, aks: (await this.getCredentials()).token }, + }; + } + + async getCredentials(): Promise<{ token?: string }> { + return { + token: await this.microsoftAuthApi.getAccessToken( + '6dae42f8-4368-4678-94ff-3960e28e3630/user.read', + ), + }; + } +} diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts index a83cbcfaa4..14e574022a 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.test.ts @@ -39,11 +39,18 @@ const requestBody: KubernetesRequestBody = { }; describe('KubernetesAuthProviders tests', () => { - const kap = new KubernetesAuthProviders({ - googleAuthApi: new MockAuthApi('googleToken'), - oidcProviders: { - okta: new MockAuthApi('oktaToken'), - }, + let microsoftAuthApi: MockAuthApi; + let kap: KubernetesAuthProviders; + + beforeEach(() => { + microsoftAuthApi = new MockAuthApi('aksToken'); + kap = new KubernetesAuthProviders({ + microsoftAuthApi, + googleAuthApi: new MockAuthApi('googleToken'), + oidcProviders: { + okta: new MockAuthApi('oktaToken'), + }, + }); }); it('adds token to request body for google authProvider', async () => { @@ -52,6 +59,15 @@ describe('KubernetesAuthProviders tests', () => { expect(details.auth?.google).toBe('googleToken'); }); + it('adds token to request body for aks authProvider', async () => { + const details = await kap.decorateRequestBodyForAuth('aks', requestBody); + + expect(details.auth?.aks).toBe('aksToken'); + expect(microsoftAuthApi.getAccessToken).toHaveBeenCalledWith( + '6dae42f8-4368-4678-94ff-3960e28e3630/user.read', + ); + }); + it('adds token to request body for oidc authProvider', async () => { const details = await kap.decorateRequestBodyForAuth( 'oidc.okta', diff --git a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts index 836641f1ed..84154d5e96 100644 --- a/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts +++ b/plugins/kubernetes/src/kubernetes-auth-provider/KubernetesAuthProviders.ts @@ -20,6 +20,7 @@ import { GoogleKubernetesAuthProvider } from './GoogleKubernetesAuthProvider'; import { ServerSideKubernetesAuthProvider } from './ServerSideAuthProvider'; import { OAuthApi, OpenIdConnectApi } from '@backstage/core-plugin-api'; import { OidcKubernetesAuthProvider } from './OidcKubernetesAuthProvider'; +import { AksKubernetesAuthProvider } from './AksKubernetesAuthProvider'; export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { private readonly kubernetesAuthProviderMap: Map< @@ -28,6 +29,7 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { >; constructor(options: { + microsoftAuthApi: OAuthApi; googleAuthApi: OAuthApi; oidcProviders?: { [key: string]: OpenIdConnectApi }; }) { @@ -56,6 +58,10 @@ export class KubernetesAuthProviders implements KubernetesAuthProvidersApi { 'localKubectlProxy', new ServerSideKubernetesAuthProvider(), ); + this.kubernetesAuthProviderMap.set( + 'aks', + new AksKubernetesAuthProvider(options.microsoftAuthApi), + ); if (options.oidcProviders) { Object.keys(options.oidcProviders).forEach(provider => { diff --git a/plugins/kubernetes/src/plugin.ts b/plugins/kubernetes/src/plugin.ts index e10b4856b7..02c7bfd2d6 100644 --- a/plugins/kubernetes/src/plugin.ts +++ b/plugins/kubernetes/src/plugin.ts @@ -87,7 +87,11 @@ export const kubernetesPlugin = createPlugin({ onelogin: oneloginAuthApi, }; - return new KubernetesAuthProviders({ googleAuthApi, oidcProviders }); + return new KubernetesAuthProviders({ + microsoftAuthApi, + googleAuthApi, + oidcProviders, + }); }, }), ], diff --git a/plugins/lighthouse-backend/CHANGELOG.md b/plugins/lighthouse-backend/CHANGELOG.md index 81da2807af..5b0d9d8ecc 100644 --- a/plugins/lighthouse-backend/CHANGELOG.md +++ b/plugins/lighthouse-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-lighthouse-backend +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-lighthouse-common@0.1.1 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index 351ee3fb7e..eb48a5673d 100644 --- a/plugins/lighthouse-backend/package.json +++ b/plugins/lighthouse-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse-backend", "description": "Backend functionalities for lighthouse", - "version": "0.2.1-next.1", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index 67aa76b0f9..b8d70898fd 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-lighthouse +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-lighthouse-common@0.1.1 + +## 0.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.4.3-next.1 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 7afa358f76..377614ca97 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.4.3-next.1", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/linguist-backend/CHANGELOG.md b/plugins/linguist-backend/CHANGELOG.md index 5096043450..a0ab8c5990 100644 --- a/plugins/linguist-backend/CHANGELOG.md +++ b/plugins/linguist-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-linguist-backend +## 0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-linguist-common@0.1.0 + ## 0.2.2-next.1 ### Patch Changes diff --git a/plugins/linguist-backend/README.md b/plugins/linguist-backend/README.md index 46c067fb5a..c1201fc70a 100644 --- a/plugins/linguist-backend/README.md +++ b/plugins/linguist-backend/README.md @@ -57,7 +57,11 @@ Here's how to get the backend up and running: 4. Now run `yarn start-backend` from the repo root 5. Finally open `http://localhost:7007/api/linguist/health` in a browser and it should return `{"status":"ok"}` -## Batch Size +## Plugin Option + +The Linguist backend has various plugin options that you can provide to the `createRouter` function in your `packages/backend/src/plugins/linguist.ts` file that will allow you to configure various aspects of how it works. The following sections go into the details of these options + +### Batch Size The Linguist backend is setup to process entities by acting as a queue where it will pull down all the applicable entities from the Catalog and add them to it's database (saving just the `entityRef`). Then it will grab the `n` oldest entities that have not been processed to determine their languages and process them. To control the batch size simply provide that to the `createRouter` function in your `packages/backend/src/plugins/linguist.ts` like this: @@ -67,7 +71,7 @@ return createRouter({ schedule: schedule, batchSize: 40 }, { ...env }); **Note:** The default batch size is 20 -## Kind +### Kind The default setup only processes entities of kind `['API', 'Component', 'Template']`. To control the `kind` that are processed provide that to the `createRouter` function in your `packages/backend/src/plugins/linguist.ts` like this: @@ -75,7 +79,7 @@ The default setup only processes entities of kind `['API', 'Component', 'Templat return createRouter({ schedule: schedule, kind: ['Component'] }, { ...env }); ``` -## Refresh +### Refresh The default setup will only generate the language breakdown for entities with the linguist annotation that have not been generated yet. If you want this process to also refresh the data you can do so by adding the `age` (as a `HumanDuration`) in your `packages/backend/src/plugins/linguist.ts` when you call `createRouter`: @@ -85,7 +89,7 @@ return createRouter({ schedule: schedule, age: { days: 30 } }, { ...env }); With the `age` setup like this if the language breakdown is older than 15 days it will get regenerated. It's recommended that if you choose to use this configuration to set it to a large value - 30, 90, or 180 - as this data generally does not change drastically. -## Linguist JS options +### Linguist JS options The default setup will use the default [linguist-js](https://www.npmjs.com/package/linguist-js) options, a full list of the available options can be found [here](https://www.npmjs.com/package/linguist-js#API). @@ -96,7 +100,7 @@ return createRouter( ); ``` -## Use Source Location +### Use Source Location You may wish to use the `backstage.io/source-location` annotation over using the `backstage.io/linguist` as you may not be able to quickly add that annotation to your Entities. To do this you'll just need to set the `useSourceLocation` boolean to `true` in your `packages/backend/src/plugins/linguist.ts` when you call `createRouter`: diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md index a47f123ac4..294d569ff7 100644 --- a/plugins/linguist-backend/api-report.md +++ b/plugins/linguist-backend/api-report.md @@ -3,16 +3,13 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { EntityResults } from '@backstage/plugin-linguist-common'; import express from 'express'; import { HumanDuration } from '@backstage/types'; -import { Knex } from 'knex'; import { Languages } from '@backstage/plugin-linguist-common'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { ProcessedEntity } from '@backstage/plugin-linguist-common'; import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { TokenManager } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; @@ -24,56 +21,13 @@ export function createRouter( ): Promise; // @public (undocumented) -export class LinguistBackendApi { - constructor( - logger: Logger, - store: LinguistBackendStore, - urlReader: UrlReader, - discovery: PluginEndpointDiscovery, - tokenManager: TokenManager, - age?: HumanDuration, - batchSize?: number, - useSourceLocation?: boolean, - kind?: string[], - linguistJsOptions?: Record, - ); +export interface LinguistBackendApi { // (undocumented) getEntityLanguages(entityRef: string): Promise; // (undocumented) processEntities(): Promise; } -// @public (undocumented) -export class LinguistBackendDatabase implements LinguistBackendStore { - constructor(db: Knex); - // (undocumented) - static create(knex: Knex): Promise; - // (undocumented) - getEntityResults(entityRef: string): Promise; - // (undocumented) - getProcessedEntities(): Promise; - // (undocumented) - getUnprocessedEntities(): Promise; - // (undocumented) - insertEntityResults(entityLanguages: EntityResults): Promise; - // (undocumented) - insertNewEntity(entityRef: string): Promise; -} - -// @public (undocumented) -export interface LinguistBackendStore { - // (undocumented) - getEntityResults(entityRef: string): Promise; - // (undocumented) - getProcessedEntities(): Promise; - // (undocumented) - getUnprocessedEntities(): Promise; - // (undocumented) - insertEntityResults(entityLanguages: EntityResults): Promise; - // (undocumented) - insertNewEntity(entityRef: string): Promise; -} - // @public (undocumented) export interface PluginOptions { // (undocumented) diff --git a/plugins/linguist-backend/migrations/20230216_remove_processed_date_default.js b/plugins/linguist-backend/migrations/20230216_remove_processed_date_default.js new file mode 100644 index 0000000000..5aaf02216e --- /dev/null +++ b/plugins/linguist-backend/migrations/20230216_remove_processed_date_default.js @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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. + */ + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Sqlite does not support this raw SQL + if (!knex.client.config.client.includes('sqlite3')) { + await knex.raw( + 'ALTER TABLE entity_result ALTER COLUMN processed_date DROP DEFAULT;', + ); + } +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + // Sqlite does not support this raw SQL + if (!knex.client.config.client.includes('sqlite3')) { + await knex.raw( + 'ALTER TABLE entity_result ALTER COLUMN processed_date SET DEFAULT now();', + ); + } +}; diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json index f3feacb740..7b32126f1e 100644 --- a/plugins/linguist-backend/package.json +++ b/plugins/linguist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist-backend", - "version": "0.2.2-next.1", + "version": "0.2.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -44,6 +44,7 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", diff --git a/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts new file mode 100644 index 0000000000..1b0a4f4673 --- /dev/null +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts @@ -0,0 +1,416 @@ +/* + * Copyright 2023 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 { + getVoidLogger, + ReadTreeResponse, + ServerTokenManager, + UrlReader, +} from '@backstage/backend-common'; +import { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client'; +import { Results } from 'linguist-js/dist/types'; +import { DateTime } from 'luxon'; +import { LinguistBackendStore } from '../db'; +import { kindOrDefault, LinguistBackendClient } from './LinguistBackendClient'; +import fs from 'fs-extra'; +import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; + +const linguistResultMock = Promise.resolve({ + files: { + count: 4, + bytes: 6010, + results: { + '/src/index.ts': 'TypeScript', + '/src/cli.js': 'JavaScript', + '/readme.md': 'Markdown', + '/no-lang': null, + }, + }, + languages: { + count: 3, + bytes: 6000, + results: { + JavaScript: { type: 'programming', bytes: 1000, color: '#f1e05a' }, + TypeScript: { type: 'programming', bytes: 2000, color: '#2b7489' }, + Markdown: { type: 'prose', bytes: 3000, color: '#083fa1' }, + }, + }, + unknown: { + count: 1, + bytes: 10, + filenames: { + 'no-lang': 10, + }, + extensions: {}, + }, +} as Results); + +describe('kindOrDefault', () => { + it('should return default kind when undefined', () => { + expect(kindOrDefault()).toEqual(['API', 'Component', 'Template']); + }); + it('should return the default kind when empty', () => { + expect(kindOrDefault([])).toEqual(['API', 'Component', 'Template']); + }); + it('should return provided kind when not empty', () => { + expect(kindOrDefault(['API'])).toEqual(['API']); + }); +}); + +describe('Linguist backend API', () => { + const logger = getVoidLogger(); + + const store: jest.Mocked = { + insertEntityResults: jest.fn(), + insertNewEntity: jest.fn(), + getEntityResults: jest.fn(), + getProcessedEntities: jest.fn(), + getUnprocessedEntities: jest.fn(), + getAllEntities: jest.fn(), + deleteEntity: jest.fn(), + }; + + const urlReader: jest.Mocked = { + readTree: jest.fn(), + search: jest.fn(), + readUrl: jest.fn(), + }; + + const catalogApi: jest.Mocked = { + getEntities: jest.fn(), + getEntityByRef: jest.fn(), + } as any; + + const tokenManager = ServerTokenManager.noop(); + + const api = new LinguistBackendClient( + logger, + store, + urlReader, + tokenManager, + catalogApi, + ); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should get languages for an entity', async () => { + store.getEntityResults.mockResolvedValue({ + languageCount: 1, + totalBytes: 2205, + processedDate: '2023-02-15T20:10:21.378Z', + breakdown: [ + { + name: 'YAML', + percentage: 100, + bytes: 2205, + type: 'data', + color: '#cb171e', + }, + ], + }); + + const entityRef = 'template:default/create-react-app-template'; + const languages = await api.getEntityLanguages(entityRef); + expect(languages).toEqual({ + languageCount: 1, + totalBytes: 2205, + processedDate: '2023-02-15T20:10:21.378Z', + breakdown: [ + { + name: 'YAML', + percentage: 100, + bytes: 2205, + type: 'data', + color: '#cb171e', + }, + ], + }); + }); + + it('should insert new entities', async () => { + const testEntityListResponse: GetEntitiesResponse = { + items: [ + { + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-one', + }, + kind: 'Component', + }, + { + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-two', + }, + kind: 'Component', + }, + { + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-three', + }, + kind: 'Component', + }, + ], + }; + catalogApi.getEntities.mockResolvedValue(testEntityListResponse); + + await api.addNewEntities(); + expect(store.insertNewEntity).toHaveBeenCalledTimes(3); + }); + + it('should delete entities not in Catalog', async () => { + store.getAllEntities.mockResolvedValue([ + 'component:default/service-one', + 'component:default/stale-service-two', + ]); + + catalogApi.getEntityByRef.mockResolvedValueOnce({ + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-one', + }, + kind: 'Component', + }); + + await api.cleanEntities(); + expect(store.deleteEntity).toHaveBeenCalledTimes(1); + }); + + it('should get default entity overview', async () => { + store.getProcessedEntities.mockResolvedValue([ + { + entityRef: 'component:default/service-one', + processedDate: DateTime.now().toJSDate(), + }, + { + entityRef: 'component:default/stale-service-two', + processedDate: DateTime.now().minus({ days: 45 }).toJSDate(), + }, + ]); + + store.getUnprocessedEntities.mockResolvedValue([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + ]); + + const overview = await api.getEntitiesOverview(); + expect(overview.entityCount).toEqual(5); + expect(overview.processedCount).toEqual(2); + expect(overview.staleCount).toEqual(0); + expect(overview.pendingCount).toEqual(3); + expect(overview.filteredEntities).toEqual([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + ]); + }); + + it('should get entity overview with stale items', async () => { + const apiWithAge = new LinguistBackendClient( + logger, + store, + urlReader, + tokenManager, + catalogApi, + { days: 5 }, + ); + store.getProcessedEntities.mockResolvedValue([ + { + entityRef: 'component:default/service-one', + processedDate: DateTime.now().toJSDate(), + }, + { + entityRef: 'component:default/stale-service-two', + processedDate: DateTime.now().minus({ days: 45 }).toJSDate(), + }, + ]); + + store.getUnprocessedEntities.mockResolvedValue([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + ]); + + const overview = await apiWithAge.getEntitiesOverview(); + expect(overview.entityCount).toEqual(5); + expect(overview.processedCount).toEqual(2); + expect(overview.staleCount).toEqual(1); + expect(overview.pendingCount).toEqual(4); + expect(overview.filteredEntities).toEqual([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + 'component:default/stale-service-two', + ]); + }); + + it('should generate and save languages for an entity', async () => { + const spy = jest + .spyOn(api, 'getLinguistResults') + .mockImplementation(() => linguistResultMock); + + urlReader.readTree.mockResolvedValueOnce({ + files: async () => [ + { + content: async () => Buffer.from('-- XXX: code-data', 'utf8'), + path: 'my-file.js', + }, + ], + dir: async () => '/temp/my-code', + } as ReadTreeResponse); + + const fsSpy = jest.spyOn(fs, 'remove'); + + await api.generateEntityLanguages( + 'component:default/fake-service', + 'https://some.fake/service/', + ); + expect(api.getLinguistResults).toHaveBeenCalled(); + expect(store.insertEntityResults).toHaveBeenCalled(); + expect(fs.remove).toHaveBeenCalled(); + spy.mockClear(); + fsSpy.mockClear(); + }); + + it('should generate languages for entities using default', async () => { + store.getProcessedEntities.mockResolvedValue([ + { + entityRef: 'component:default/service-one', + processedDate: DateTime.now().toJSDate(), + }, + { + entityRef: 'component:default/stale-service-two', + processedDate: DateTime.now().minus({ days: 45 }).toJSDate(), + }, + ]); + + store.getUnprocessedEntities.mockResolvedValue([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + ]); + + const entity = { + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-one', + annotations: { + [LINGUIST_ANNOTATION]: 'https://some.fake/service/', + }, + }, + kind: 'Component', + }; + + catalogApi.getEntityByRef.mockResolvedValue(entity); + + const resultsSpy = jest + .spyOn(api, 'getLinguistResults') + .mockImplementation(() => linguistResultMock); + + urlReader.readTree.mockResolvedValue({ + files: async () => [ + { + content: async () => Buffer.from('-- XXX: code-data', 'utf8'), + path: 'my-file.js', + }, + ], + dir: async () => '/temp/my-code', + } as ReadTreeResponse); + + const fsSpy = jest.spyOn(fs, 'remove'); + + const generateEntityLanguages = jest.spyOn(api, 'generateEntityLanguages'); + await api.generateEntitiesLanguages(); + expect(generateEntityLanguages).toHaveBeenCalledTimes(3); + + generateEntityLanguages.mockClear(); + resultsSpy.mockClear(); + fsSpy.mockClear(); + }); + + it('should generate languages for entities using defined batch size', async () => { + const apiWithBatchSize = new LinguistBackendClient( + logger, + store, + urlReader, + tokenManager, + catalogApi, + undefined, + 2, + ); + + store.getProcessedEntities.mockResolvedValue([ + { + entityRef: 'component:default/service-one', + processedDate: DateTime.now().toJSDate(), + }, + { + entityRef: 'component:default/stale-service-two', + processedDate: DateTime.now().minus({ days: 45 }).toJSDate(), + }, + ]); + + store.getUnprocessedEntities.mockResolvedValue([ + 'component:default/service-three', + 'component:default/service-four', + 'component:default/service-five', + ]); + + const entity = { + apiVersion: 'backstage.io/v1beta1', + metadata: { + name: 'service-one', + annotations: { + [LINGUIST_ANNOTATION]: 'https://some.fake/service/', + }, + }, + kind: 'Component', + }; + + catalogApi.getEntityByRef.mockResolvedValue(entity); + + const resultsSpy = jest + .spyOn(apiWithBatchSize, 'getLinguistResults') + .mockImplementation(() => linguistResultMock); + + urlReader.readTree.mockResolvedValue({ + files: async () => [ + { + content: async () => Buffer.from('-- XXX: code-data', 'utf8'), + path: 'my-file.js', + }, + ], + dir: async () => '/temp/my-code', + } as ReadTreeResponse); + + const fsSpy = jest.spyOn(fs, 'remove'); + + const generateEntityLanguages = jest.spyOn( + apiWithBatchSize, + 'generateEntityLanguages', + ); + await apiWithBatchSize.generateEntitiesLanguages(); + expect(generateEntityLanguages).toHaveBeenCalledTimes(2); + + generateEntityLanguages.mockClear(); + resultsSpy.mockClear(); + fsSpy.mockClear(); + }); +}); diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.ts similarity index 76% rename from plugins/linguist-backend/src/api/LinguistBackendApi.ts rename to plugins/linguist-backend/src/api/LinguistBackendClient.ts index df7e30a7b0..5a84201bcb 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendApi.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.ts @@ -22,14 +22,10 @@ import { } from '@backstage/plugin-linguist-common'; import { CATALOG_FILTER_EXISTS, - CatalogClient, GetEntitiesRequest, + CatalogApi, } from '@backstage/catalog-client'; -import { - PluginEndpointDiscovery, - TokenManager, - UrlReader, -} from '@backstage/backend-common'; +import { TokenManager, UrlReader } from '@backstage/backend-common'; import { DateTime } from 'luxon'; import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; @@ -43,16 +39,22 @@ import { } from '@backstage/catalog-model'; import { assertError } from '@backstage/errors'; import { HumanDuration } from '@backstage/types'; +import { Results } from 'linguist-js/dist/types'; /** @public */ -export class LinguistBackendApi { +export interface LinguistBackendApi { + getEntityLanguages(entityRef: string): Promise; + processEntities(): Promise; +} + +/** @public */ +export class LinguistBackendClient implements LinguistBackendApi { private readonly logger: Logger; private readonly store: LinguistBackendStore; private readonly urlReader: UrlReader; - private readonly discovery: PluginEndpointDiscovery; private readonly tokenManager: TokenManager; - private readonly catalogClient: CatalogClient; + private readonly catalogApi: CatalogApi; private readonly age?: HumanDuration; private readonly batchSize?: number; private readonly useSourceLocation?: boolean; @@ -62,8 +64,8 @@ export class LinguistBackendApi { logger: Logger, store: LinguistBackendStore, urlReader: UrlReader, - discovery: PluginEndpointDiscovery, tokenManager: TokenManager, + catalogApi: CatalogApi, age?: HumanDuration, batchSize?: number, useSourceLocation?: boolean, @@ -73,9 +75,8 @@ export class LinguistBackendApi { this.logger = logger; this.store = store; this.urlReader = urlReader; - this.discovery = discovery; this.tokenManager = tokenManager; - this.catalogClient = new CatalogClient({ discoveryApi: this.discovery }); + this.catalogApi = catalogApi; this.batchSize = batchSize; this.age = age; this.useSourceLocation = useSourceLocation; @@ -83,23 +84,25 @@ export class LinguistBackendApi { this.linguistJsOptions = linguistJsOptions; } - public async getEntityLanguages(entityRef: string): Promise { + async getEntityLanguages(entityRef: string): Promise { this.logger?.debug(`Getting languages for entity "${entityRef}"`); return this.store.getEntityResults(entityRef); } - public async processEntities() { + async processEntities(): Promise { this.logger?.info('Updating list of entities'); - await this.addNewEntities(); - this.logger?.info('Processing applicable entities through Linguist'); + this.logger?.info('Cleaning list of entities'); + await this.cleanEntities(); + this.logger?.info('Processing applicable entities through Linguist'); await this.generateEntitiesLanguages(); } - private async addNewEntities() { + /** @internal */ + async addNewEntities(): Promise { const annotationKey = this.useSourceLocation ? ANNOTATION_SOURCE_LOCATION : LINGUIST_ANNOTATION; @@ -112,7 +115,7 @@ export class LinguistBackendApi { }; const { token } = await this.tokenManager.getToken(); - const response = await this.catalogClient.getEntities(request, { token }); + const response = await this.catalogApi.getEntities(request, { token }); const entities = response.items; entities.forEach(entity => { @@ -121,7 +124,25 @@ export class LinguistBackendApi { }); } - private async generateEntitiesLanguages() { + /** @internal */ + async cleanEntities(): Promise { + this.logger?.info('Cleaning entities in Linguist queue'); + const allEntities = await this.store.getAllEntities(); + + for (const entityRef of allEntities) { + const result = await this.catalogApi.getEntityByRef(entityRef); + + if (!result) { + this.logger?.info( + `Entity ${entityRef} was not found in the Catalog, it will be deleted`, + ); + await this.store.deleteEntity(entityRef); + } + } + } + + /** @internal */ + async generateEntitiesLanguages(): Promise { const entitiesOverview = await this.getEntitiesOverview(); this.logger?.info( `Entities overview: Entity: ${entitiesOverview.entityCount}, Processed: ${entitiesOverview.processedCount}, Pending: ${entitiesOverview.pendingCount}, Stale ${entitiesOverview.staleCount}`, @@ -131,9 +152,10 @@ export class LinguistBackendApi { 0, this.batchSize ?? 20, ); - entities.forEach(async entityRef => { + + for (const entityRef of entities) { const { token } = await this.tokenManager.getToken(); - const entity = await this.catalogClient.getEntityByRef(entityRef, { + const entity = await this.catalogApi.getEntityByRef(entityRef, { token, }); const annotationKey = this.useSourceLocation @@ -153,10 +175,11 @@ export class LinguistBackendApi { `Unable to process "${entityRef}" using "${url}", message: ${error.message}, stack: ${error.stack}`, ); } - }); + } } - private async getEntitiesOverview(): Promise { + /** @internal */ + async getEntitiesOverview(): Promise { this.logger?.debug('Getting pending entities'); const processedEntities = await this.store.getProcessedEntities(); @@ -169,10 +192,10 @@ export class LinguistBackendApi { .map(pe => pe.entityRef); const unprocessedEntities = await this.store.getUnprocessedEntities(); - const filteredEntities = staleEntities.concat(unprocessedEntities); + const filteredEntities = unprocessedEntities.concat(staleEntities); const entitiesOverview: EntitiesOverview = { - entityCount: unprocessedEntities.length, + entityCount: unprocessedEntities.length + processedEntities.length, processedCount: processedEntities.length, staleCount: staleEntities.length, pendingCount: filteredEntities.length, @@ -182,7 +205,8 @@ export class LinguistBackendApi { return entitiesOverview; } - private async generateEntityLanguages( + /** @internal */ + async generateEntityLanguages( entityRef: string, url: string, ): Promise { @@ -193,7 +217,7 @@ export class LinguistBackendApi { const readTreeResponse = await this.urlReader.readTree(url); const dir = await readTreeResponse.dir(); - const results = await linguist(dir, this.linguistJsOptions); + const results = await this.getLinguistResults(dir); try { const totalBytes = results.languages.bytes; @@ -233,9 +257,15 @@ export class LinguistBackendApi { await fs.remove(dir); } } + + /** @internal */ + async getLinguistResults(dir: string): Promise { + const results = await linguist(dir, this.linguistJsOptions); + return results; + } } -export function kindOrDefault(kind?: string[]) { +export function kindOrDefault(kind?: string[]): string[] { if (!kind || kind.length === 0) { return ['API', 'Component', 'Template']; } diff --git a/plugins/linguist-backend/src/api/index.ts b/plugins/linguist-backend/src/api/index.ts index a88fa051d4..b3f73587e7 100644 --- a/plugins/linguist-backend/src/api/index.ts +++ b/plugins/linguist-backend/src/api/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { LinguistBackendApi } from './LinguistBackendApi'; +export type { LinguistBackendApi } from './LinguistBackendClient'; diff --git a/plugins/linguist-backend/src/db/LinguistBackendDatabase.test.ts b/plugins/linguist-backend/src/db/LinguistBackendDatabase.test.ts new file mode 100644 index 0000000000..5998ddfc1e --- /dev/null +++ b/plugins/linguist-backend/src/db/LinguistBackendDatabase.test.ts @@ -0,0 +1,200 @@ +/* + * 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 as KnexType, Knex } from 'knex'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import { + LinguistBackendDatabase, + LinguistBackendStore, +} from './LinguistBackendDatabase'; +import { Languages, ProcessedEntity } from '@backstage/plugin-linguist-common'; + +function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, +) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + +const rawDbEntityResultRows = [ + { + id: '14b32439-848a-49b2-92a4-98753f932606', + entity_ref: 'template:default/create-react-app-template', + languages: undefined, + processed_date: undefined, + }, + { + id: '8c85d3ec-ccea-4b29-9de9-ccdd7e5ba452', + entity_ref: 'template:default/docs-template', + languages: undefined, + processed_date: undefined, + }, + { + id: 'b922c87b-37bc-4505-b4af-70a1438decda', + entity_ref: 'template:default/pull-request', + languages: + '{"languageCount":1,"totalBytes":2205,"processedDate":"2023-02-15T20:10:21.378Z","breakdown":[{"name":"YAML","percentage":100,"bytes":2205,"type":"data","color":"#cb171e"}]}', + processed_date: new Date('2023-02-15 20:10:21.378Z'), + }, + { + id: 'bd555e6d-a3d0-4b48-a930-194db8f80db7', + entity_ref: 'template:default/react-ssr-template', + languages: + '{"languageCount":8,"totalBytes":8988,"processedDate":"2023-02-15T20:10:21.388Z","breakdown":[{"name":"INI","percentage":2.26,"bytes":203,"type":"data","color":"#d1dbe0"},{"name":"JavaScript","percentage":5.94,"bytes":534,"type":"programming","color":"#f1e05a"},{"name":"YAML","percentage":31.09,"bytes":2794,"type":"data","color":"#cb171e"},{"name":"Markdown","percentage":11.79,"bytes":1060,"type":"prose","color":"#083fa1"},{"name":"JSON","percentage":21.09,"bytes":1896,"type":"data","color":"#292929"},{"name":"CSS","percentage":0,"bytes":0,"type":"markup","color":"#563d7c"},{"name":"TSX","percentage":26.01,"bytes":2338,"type":"programming","color":"#3178c6"},{"name":"TypeScript","percentage":1.81,"bytes":163,"type":"programming","color":"#3178c6"}]}', + processed_date: new Date('2023-02-15 20:10:21.388Z'), + }, + { + id: '4145c0cf-44e9-4e95-9d57-781af4685b28', + entity_ref: 'template:default/springboot-template', + languages: + '{"languageCount":9,"totalBytes":80986,"processedDate":"2023-02-15T20:10:21.419Z","breakdown":[{"name":"Shell","percentage":0.16,"bytes":130,"type":"programming","color":"#89e051"},{"name":"INI","percentage":0.35,"bytes":286,"type":"data","color":"#d1dbe0"},{"name":"Dockerfile","percentage":0.3,"bytes":246,"type":"programming","color":"#384d54"},{"name":"YAML","percentage":3.92,"bytes":3171,"type":"data","color":"#cb171e"},{"name":"Markdown","percentage":1.31,"bytes":1059,"type":"prose","color":"#083fa1"},{"name":"XML","percentage":10.48,"bytes":8491,"type":"data","color":"#0060ac"},{"name":"Java","percentage":1.8,"bytes":1455,"type":"programming","color":"#b07219"},{"name":"Text","percentage":81.22,"bytes":65780,"type":"prose"},{"name":"Protocol Buffer","percentage":0.45,"bytes":368,"type":"data"}]}', + processed_date: new Date('2023-02-15 20:10:21.419Z'), + }, +]; + +describe('Linguist database', () => { + const databases = TestDatabases.create(); + let store: LinguistBackendStore; + let testDbClient: Knex; + beforeAll(async () => { + testDbClient = await databases.init('SQLITE_3'); + const database = createDatabaseManager(testDbClient); + + store = await LinguistBackendDatabase.create(await database.getClient()); + }); + beforeEach(async () => { + await testDbClient.batchInsert('entity_result', rawDbEntityResultRows); + }); + afterEach(async () => { + await testDbClient('entity_result').delete(); + }); + + it('should be able to return entity results', async () => { + const validLanguagesResult: Languages = { + languageCount: 1, + totalBytes: 2205, + processedDate: '2023-02-15T20:10:21.378Z', + breakdown: [ + { + name: 'YAML', + percentage: 100, + bytes: 2205, + type: 'data', + color: '#cb171e', + }, + ], + }; + + const entityResult = await store.getEntityResults( + 'template:default/pull-request', + ); + expect(entityResult).toMatchObject(validLanguagesResult); + }); + + it('should return empty entity results when not found', async () => { + const validEmptyLanguagesResult: Languages = { + languageCount: 0, + totalBytes: 0, + processedDate: 'undefined', + breakdown: [], + }; + + const entityResult = await store.getEntityResults( + 'template:default/create-react-app-template', + ); + expect(entityResult).toMatchObject(validEmptyLanguagesResult); + }); + + it('should be able to return unprocessed entities', async () => { + const validUnprocessedEntities: string[] = [ + 'template:default/create-react-app-template', + 'template:default/docs-template', + ]; + + const unprocessedEntities = await store.getUnprocessedEntities(); + + expect(unprocessedEntities).toMatchObject(validUnprocessedEntities); + }); + + it('should return string[] when there is no unprocessed entities', async () => { + await testDbClient('entity_result').delete(); + const unprocessedEntities = await store.getUnprocessedEntities(); + + expect(unprocessedEntities).toMatchObject([]); + }); + + it('should be able to return processed entities', async () => { + const validProcessedEntities: ProcessedEntity[] = [ + { + entityRef: 'template:default/pull-request', + processedDate: new Date('2023-02-15 20:10:21.378Z'), + }, + { + entityRef: 'template:default/react-ssr-template', + processedDate: new Date('2023-02-15 20:10:21.388Z'), + }, + { + entityRef: 'template:default/springboot-template', + processedDate: new Date('2023-02-15 20:10:21.419Z'), + }, + ]; + + const processedEntities = await store.getProcessedEntities(); + + expect(processedEntities).toMatchObject(validProcessedEntities); + }); + + it('should return string[] when there is no processed entities', async () => { + await testDbClient('entity_result').delete(); + const unprocessedEntities = await store.getProcessedEntities(); + + expect(unprocessedEntities).toMatchObject([]); + }); + + it('should insert new entities and ignore duplicates', async () => { + const before = testDbClient.from('entity_result').count(); + + await store.insertNewEntity('component:/default/new-entity-one'); + await store.insertNewEntity('component:/default/new-entity-two'); + await store.insertNewEntity('template:default/pull-request'); + + const after = testDbClient.from('entity_result').count(); + + expect(before).toEqual(after); + }); + + it('should get all entities', async () => { + const allEntities = await store.getAllEntities(); + + expect(allEntities.length).toEqual(5); + }); + + it('should delete entity by its entityRef', async () => { + const before = await testDbClient.from('entity_result').count(); + + await store.deleteEntity('template:default/create-react-app-template'); + + const after = await testDbClient.from('entity_result').count(); + + expect(before).toEqual([{ 'count(*)': 5 }]); + expect(after).toEqual([{ 'count(*)': 4 }]); + }); +}); diff --git a/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts b/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts index cf93374800..5a59d18e90 100644 --- a/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts +++ b/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts @@ -26,8 +26,8 @@ import { export type RawDbEntityResultRow = { id: string; entity_ref: string; - languages: string; - processed_date: Date; + languages?: string; + processed_date?: Date; }; /** @public */ @@ -35,8 +35,10 @@ export interface LinguistBackendStore { insertEntityResults(entityLanguages: EntityResults): Promise; insertNewEntity(entityRef: string): Promise; getEntityResults(entityRef: string): Promise; - getProcessedEntities(): Promise; - getUnprocessedEntities(): Promise; + getProcessedEntities(): Promise; + getUnprocessedEntities(): Promise; + getAllEntities(): Promise; + deleteEntity(entityRef: string): Promise; } const migrationsDir = resolvePackagePath( @@ -91,7 +93,7 @@ export class LinguistBackendDatabase implements LinguistBackendStore { .where({ entity_ref: entityRef }) .first(); - if (!entityResults) { + if (!entityResults || !entityResults.languages) { const emptyResults: Languages = { languageCount: 0, totalBytes: 0, @@ -108,7 +110,7 @@ export class LinguistBackendDatabase implements LinguistBackendStore { } } - async getProcessedEntities(): Promise { + async getProcessedEntities(): Promise { const rawEntities = await this.db('entity_result') .whereNotNull('processed_date') .whereNotNull('languages'); @@ -118,9 +120,20 @@ export class LinguistBackendDatabase implements LinguistBackendStore { } const processedEntities = rawEntities.map(rawEntity => { + // Note: processed_date should never be null, this is handled by the DB query above + let processedDate = new Date(); + if (rawEntity.processed_date) { + // SQLite will return a Timestamp whereas Postgres will return a proper Date + // This tests to see if we are getting a timestamp and convert if needed + processedDate = new Date(+rawEntity.processed_date.toString()); + if (isNaN(+rawEntity.processed_date.toString())) { + processedDate = rawEntity.processed_date; + } + } + const processEntity = { entityRef: rawEntity.entity_ref, - processedDate: rawEntity.processed_date, + processedDate, }; return processEntity; @@ -129,8 +142,11 @@ export class LinguistBackendDatabase implements LinguistBackendStore { return processedEntities; } - async getUnprocessedEntities(): Promise { + async getUnprocessedEntities(): Promise { const rawEntities = await this.db('entity_result') + // TODO(ahhhndre) processed_date should always be null as well but it had a default to the current date + // once the default has been removed and released, we can then come back an enable this check + // .whereNull('processed_date') .whereNull('languages') .orderBy('created_at', 'asc'); @@ -144,4 +160,24 @@ export class LinguistBackendDatabase implements LinguistBackendStore { return unprocessedEntities; } + + async getAllEntities(): Promise { + const rawEntities = await this.db('entity_result'); + + if (!rawEntities) { + return []; + } + + const allEntities = rawEntities.map(rawEntity => { + return rawEntity.entity_ref; + }); + + return allEntities; + } + + async deleteEntity(entityRef: string): Promise { + await this.db('entity_result') + .where('entity_ref', entityRef) + .delete(); + } } diff --git a/plugins/linguist-backend/src/index.ts b/plugins/linguist-backend/src/index.ts index da1e0ffb00..37ecf2d47f 100644 --- a/plugins/linguist-backend/src/index.ts +++ b/plugins/linguist-backend/src/index.ts @@ -15,6 +15,4 @@ */ export * from './service/router'; -export { LinguistBackendApi } from './api'; -export { LinguistBackendDatabase } from './db'; -export type { LinguistBackendStore } from './db'; +export type { LinguistBackendApi } from './api'; diff --git a/plugins/linguist-backend/src/service/router.test.ts b/plugins/linguist-backend/src/service/router.test.ts index b8bde9d35d..7ab8f1c238 100644 --- a/plugins/linguist-backend/src/service/router.test.ts +++ b/plugins/linguist-backend/src/service/router.test.ts @@ -73,7 +73,7 @@ describe('createRouter', () => { const router = await createRouter( { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, { - linguistBackendApi, + linguistBackendApi: linguistBackendApi, discovery: testDiscovery, database: createDatabase(), reader: mockUrlReader, diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index 8d52a2e01d..9e45438ec8 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -31,6 +31,8 @@ import { TaskScheduleDefinition, } from '@backstage/backend-tasks'; import { HumanDuration } from '@backstage/types'; +import { CatalogClient } from '@backstage/catalog-client'; +import { LinguistBackendClient } from '../api/LinguistBackendClient'; /** @public */ export interface PluginOptions { @@ -74,14 +76,16 @@ export async function createRouter( await database.getClient(), ); - const linguistBackendApi = + const catalogClient = new CatalogClient({ discoveryApi: discovery }); + + const linguistBackendClient = routerOptions.linguistBackendApi || - new LinguistBackendApi( + new LinguistBackendClient( logger, linguistBackendStore, reader, - discovery, tokenManager, + catalogClient, age, batchSize, useSourceLocation, @@ -100,7 +104,7 @@ export async function createRouter( initialDelay: schedule.initialDelay, scope: schedule.scope, fn: async () => { - await linguistBackendApi.processEntities(); + await linguistBackendClient.processEntities(); }, }); } @@ -122,7 +126,7 @@ export async function createRouter( throw new Error('No entityRef was provided'); } - const entityLanguages = await linguistBackendApi.getEntityLanguages( + const entityLanguages = await linguistBackendClient.getEntityLanguages( entityRef as string, ); res.status(200).json(entityLanguages); diff --git a/plugins/linguist/CHANGELOG.md b/plugins/linguist/CHANGELOG.md index 7c3a38f09d..0d927fed5b 100644 --- a/plugins/linguist/CHANGELOG.md +++ b/plugins/linguist/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-linguist +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-linguist-common@0.1.0 + +## 0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json index e71271c03f..89faf81fd0 100644 --- a/plugins/linguist/package.json +++ b/plugins/linguist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-linguist", - "version": "0.1.3-next.1", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/microsoft-calendar/CHANGELOG.md b/plugins/microsoft-calendar/CHANGELOG.md index 6e4ca92146..a9bc798414 100644 --- a/plugins/microsoft-calendar/CHANGELOG.md +++ b/plugins/microsoft-calendar/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-microsoft-calendar +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json index a28d9a5111..070404422f 100644 --- a/plugins/microsoft-calendar/package.json +++ b/plugins/microsoft-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-microsoft-calendar", - "version": "0.1.3-next.0", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 6e3142ef09..ad52878764 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.11-next.1 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index c7d6ee5733..cebda38964 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.2.11-next.1", + "version": "0.2.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index b9beb277dc..c03b0ad933 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-newrelic +## 0.3.36 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.3.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.36-next.0 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 117d51f9e9..c8de615d73 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.36-next.0", + "version": "0.3.36", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/octopus-deploy/CHANGELOG.md b/plugins/octopus-deploy/CHANGELOG.md index 98c05807bf..66465dc514 100644 --- a/plugins/octopus-deploy/CHANGELOG.md +++ b/plugins/octopus-deploy/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-octopus-deploy +## 0.2.0 + +### Minor Changes + +- 87211bc2873: Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102. + Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object. + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.0-next.1 ### Minor Changes diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json index f8cfe04450..6597f4f69c 100644 --- a/plugins/octopus-deploy/package.json +++ b/plugins/octopus-deploy/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-octopus-deploy", - "version": "0.2.0-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 54b536cb79..a418acb8e5 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-org-react +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.7-next.1 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 7778af38db..bd7d59ba6b 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.7-next.1", + "version": "0.1.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 017d0c6db6..60bec7da2f 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,52 @@ # @backstage/plugin-org +## 0.6.8 + +### Patch Changes + +- 6e387c077a4: Changed the MembersListCard component to allow displaying aggregated members when viewing a group. Now, a toggle switch can be displayed that lets you switch between showing direct members and aggregated members. + + To enable this new feature, set the showAggregateMembersToggle prop on EntityMembersListCard: + + ```jsx + // In packages/app/src/components/catalog/EntityPage.tsx + const groupPage = ( + // ... + + // ... + ); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.6.8-next.2 + +### Patch Changes + +- 6e387c077a4: Changed the MembersListCard component to allow displaying aggregated members when viewing a group. Now, a toggle switch can be displayed that lets you switch between showing direct members and aggregated members. + + To enable this new feature, set the showAggregateMembersToggle prop on EntityMembersListCard: + + ```jsx + // In packages/app/src/components/catalog/EntityPage.tsx + const groupPage = ( + // ... + + // ... + ); + ``` + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.6.8-next.1 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 91d0d8eac2..cdbf8cd153 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.8-next.1", + "version": "0.6.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index c1ce6836eb..671772c119 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-pagerduty +## 0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.5.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.5.11-next.1 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index 85bb5ff38c..b0eea1764e 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "A Backstage plugin that integrates towards PagerDuty", - "version": "0.5.11-next.1", + "version": "0.5.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index fde89edbe9..fc478922db 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-periskop-backend +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index b453b2bc59..520c4c03ca 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.1.16-next.1", + "version": "0.1.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index f205e47356..65e6b2640d 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-periskop +## 0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.16-next.1 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 97b7c26418..b3f97452b6 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.16-next.1", + "version": "0.1.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index 02bb528853..a5a5325d16 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-permission-backend +## 0.5.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + ## 0.5.20-next.1 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 0156c96626..e1fa9785c1 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.20-next.1", + "version": "0.5.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index b2014e3e62..eb964866ce 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-permission-node +## 0.7.8 + +### Patch Changes + +- a788e715cfc: `createPermissionIntegrationRouter` now accepts rules and permissions for multiple resource types. Example: + + ```typescript + createPermissionIntegrationRouter({ + resources: [ + { + resourceType: 'resourceType-1', + permissions: permissionsResourceType1, + rules: rulesResourceType1, + }, + { + resourceType: 'resourceType-2', + permissions: permissionsResourceType2, + rules: rulesResourceType2, + }, + ], + }); + ``` + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + ## 0.7.8-next.1 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index a0187f4576..6a955ef29f 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.8-next.1", + "version": "0.7.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index 2bf296d6b4..31f1177294 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-playlist-backend +## 0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-playlist-common@0.1.6 + ## 0.3.1-next.1 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index c0ac336383..0d909104b9 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.3.1-next.1", + "version": "0.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index 363c92681d..2ecdf65cb7 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-playlist +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-permission-react@0.4.12 + - @backstage/plugin-playlist-common@0.1.6 + +## 0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index c542e6f05b..5cd050940d 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.9-next.1", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index e18a0f5a7f..6bd1c9004c 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-proxy-backend +## 0.2.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + ## 0.2.39-next.1 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index f16c87f3d7..2f44342962 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.39-next.1", + "version": "0.2.39", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/puppetdb/CHANGELOG.md b/plugins/puppetdb/CHANGELOG.md index f5bad45030..272f07dc01 100644 --- a/plugins/puppetdb/CHANGELOG.md +++ b/plugins/puppetdb/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-puppetdb +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json index 8e7cafac21..b04b3a7b1c 100644 --- a/plugins/puppetdb/package.json +++ b/plugins/puppetdb/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-puppetdb", "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", - "version": "0.1.1-next.1", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 337ba58f5f..1c1d8faffa 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar-backend +## 0.1.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + ## 0.1.42-next.1 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 170f06dcb0..8c5a2bd669 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.42-next.1", + "version": "0.1.42", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 758244bd93..ebe6cd0a7e 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-rollbar +## 0.4.18 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.4.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.4.18-next.1 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index b057062bb7..ee46f656fd 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.18-next.1", + "version": "0.4.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index f384a38e48..3add549e58 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.1.2 + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index bdc9238d2e..40fc82ecea 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", - "version": "0.1.2-next.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts index 58f84a8747..c741f6f6c0 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts @@ -88,7 +88,7 @@ export const getAndWriteAttachments = async ( }, }); if (!res.ok) { - throw ResponseError.fromResponse(res); + throw await ResponseError.fromResponse(res); } else if (res.body !== null) { fs.openSync(`${workspace}/${mkdocsDir}docs/img/${downloadTitle}`, 'w'); const writeStream = fs.createWriteStream( diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 05d8456582..1ea629a2fb 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.2.21-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index f8e494ae8b..89b2997ea3 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.21-next.1", + "version": "0.2.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 4d0b7edcc4..f040e0670e 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.2.0 + +### Minor Changes + +- 439e2986be1: Add a new scaffolder action for gitlab to ensure a group exists + +### Patch Changes + +- f1496d4ab6f: Fix input schema validation issue for gitlab actions: + + - gitlab:group:ensureExists + - gitlab:projectAccessToken:create + - gitlab:projectDeployToken:create + - gitlab:projectVariable:create + +- Updated dependencies + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## 0.2.0-next.2 + +### Minor Changes + +- 439e2986be1: Add a new scaffolder action for gitlab to ensure a group exists + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/README.md b/plugins/scaffolder-backend-module-gitlab/README.md index d071ca0cf6..340b57bbf8 100644 --- a/plugins/scaffolder-backend-module-gitlab/README.md +++ b/plugins/scaffolder-backend-module-gitlab/README.md @@ -20,9 +20,10 @@ Configure the action: // packages/backend/src/plugins/scaffolder.ts import { - createGitlabProjectAccessTokenAction, createGitlabProjectAccessTokenAction, createGitlabProjectDeployTokenAction, + createGitlabProjectVariableAction, + createGitlabGroupEnsureExistsAction, } from '@backstage/plugin-scaffolder-backend-module-gitlab'; // Create BuiltIn Actions @@ -36,18 +37,10 @@ const builtInActions = createBuiltinActions({ // Add Gitlab Actions const actions = [ ...builtInActions, - createGitlabProjectAccessTokenAction({ - integrations: integrations, - }), - createGitlabProjectAccessTokenAction({ - integrations: integrations, - }), - createGitlabProjectDeployTokenAction({ - integrations: integrations, - }), - createGitlabGroupEnsureExistsAction({ - integrations: integrations, - }), + createGitlabProjectAccessTokenAction({ integrations: integrations }), + createGitlabProjectDeployTokenAction({ integrations: integrations }), + createGitlabProjectVariableAction({ integrations: integrations }), + createGitlabGroupEnsureExistsAction({ integrations: integrations }), ]; // Create Scaffolder Router diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 96ec3445dc..f7cf6024ec 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -12,10 +12,9 @@ export const createGitlabGroupEnsureExistsAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { + path: string[]; repoUrl: string; token?: string | undefined; - } & { - path: string[]; }, { groupId?: number | undefined; @@ -27,10 +26,9 @@ export const createGitlabProjectAccessTokenAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { + projectId: string | number; repoUrl: string; token?: string | undefined; - } & { - projectId: string | number; name?: string | undefined; accessLevel?: number | undefined; scopes?: string[] | undefined; @@ -45,11 +43,10 @@ export const createGitlabProjectDeployTokenAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - repoUrl: string; - token?: string | undefined; - } & { name: string; projectId: string | number; + repoUrl: string; + token?: string | undefined; username?: string | undefined; scopes?: string[] | undefined; }, @@ -64,13 +61,12 @@ export const createGitlabProjectVariableAction: (options: { integrations: ScmIntegrationRegistry; }) => TemplateAction< { - repoUrl: string; - token?: string | undefined; - } & { key: string; value: string; projectId: string | number; + repoUrl: string; variableType: string; + token?: string | undefined; variableProtected?: boolean | undefined; masked?: boolean | undefined; raw?: boolean | undefined; diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index e338c21784..07cc725570 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitlab", - "version": "0.1.1-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts index 698d402697..f96d57e356 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts @@ -36,7 +36,7 @@ export const createGitlabGroupEnsureExistsAction = (options: { id: 'gitlab:group:ensureExists', description: 'Ensures a Gitlab group exists', schema: { - input: commonGitlabConfig.and( + input: commonGitlabConfig.merge( z.object({ path: z .array(z.string(), { diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts index 832eb4cac7..614de0e221 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts @@ -33,7 +33,7 @@ export const createGitlabProjectAccessTokenAction = (options: { return createTemplateAction({ id: 'gitlab:projectAccessToken:create', schema: { - input: commonGitlabConfig.and( + input: commonGitlabConfig.merge( z.object({ projectId: z.union([z.number(), z.string()], { description: 'Project ID', diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts index 3010bd33d2..1665d23b39 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts @@ -36,7 +36,7 @@ export const createGitlabProjectDeployTokenAction = (options: { return createTemplateAction({ id: 'gitlab:projectDeployToken:create', schema: { - input: commonGitlabConfig.and( + input: commonGitlabConfig.merge( z.object({ projectId: z.union([z.number(), z.string()], { description: 'Project ID', diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts index a6043bea01..a154c16662 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts @@ -34,7 +34,7 @@ export const createGitlabProjectVariableAction = (options: { return createTemplateAction({ id: 'gitlab:projectVariable:create', schema: { - input: commonGitlabConfig.and( + input: commonGitlabConfig.merge( z.object({ projectId: z.union([z.number(), z.string()], { description: 'Project ID', diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index cd815f8d1e..0350dfbf5c 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.14.0 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.4.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.13.2-next.2 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.4.14-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 035d698089..226e4ab3cb 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.14-next.1", + "version": "0.4.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 128526ac64..f3cf978ea6 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + +## 0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.1.5-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index fa851fd80e..2a1bf2f61f 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-sentry", - "version": "0.1.5-next.1", + "version": "0.1.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index b70c32aa52..7509ba3d76 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## 0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 0.2.18-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 77f50e3130..67f6caff59 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.18-next.1", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 0b5b88b148..d4aa251b34 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-scaffolder-backend +## 1.14.0 + +### Minor Changes + +- 67115f532b8: Expose both types of scaffolder permissions and rules through the metadata endpoint. + + The metadata endpoint now correctly exposes both types of scaffolder permissions and rules (for both the template and action resource types) through the metadata endpoint. + +- a73b3c0b097: Add ability to use `defaultNamespace` and `defaultKind` for scaffolder action `catalog:fetch` + +### Patch Changes + +- 1a48b84901c: Bump minimum required version of `vm2` to be 3.9.18 +- d20c87966a4: Bump minimum required version of `vm2` to be 3.9.17 +- 6d954de4b06: Update typing for `RouterOptions::actions` and `ScaffolderActionsExtensionPoint::addActions` to allow any kind of action being assigned to it. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1 + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-scaffolder-node@0.1.3 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + +## 1.13.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.9.1-next.2 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/plugin-scaffolder-node@0.1.3-next.2 + - @backstage/config@1.0.7 + ## 1.13.2-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index a6fd41a29e..07dd5eaf1d 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -29,6 +29,7 @@ import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-common/alpha'; import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha'; import { Schema } from 'jsonschema'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -49,6 +50,16 @@ import { ZodTypeDef } from 'zod'; // @public @deprecated (undocumented) export type ActionContext = ActionContext_2; +// @public (undocumented) +export type ActionPermissionRuleInput< + TParams extends PermissionRuleParams = PermissionRuleParams, +> = PermissionRule< + TemplateEntityStepV1beta3 | TemplateParametersV1beta3, + {}, + typeof RESOURCE_TYPE_SCAFFOLDER_ACTION, + TParams +>; + // @public export const createBuiltinActions: ( options: CreateBuiltInActionsOptions, @@ -108,6 +119,8 @@ export function createFetchCatalogEntityAction(options: { entityRef?: string | undefined; entityRefs?: string[] | undefined; optional?: boolean | undefined; + defaultKind?: string | undefined; + defaultNamespace?: string | undefined; }, { entity?: any; @@ -763,7 +776,9 @@ export interface RouterOptions { // (undocumented) logger: Logger; // (undocumented) - permissionRules?: TemplatePermissionRuleInput[]; + permissionRules?: Array< + TemplatePermissionRuleInput | ActionPermissionRuleInput + >; // (undocumented) permissions?: PermissionEvaluator; // (undocumented) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 5b9e28322d..aeb7861f4b 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.13.2-next.1", + "version": "1.14.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -92,7 +92,7 @@ "p-queue": "^6.6.2", "prom-client": "^14.0.1", "uuid": "^8.2.0", - "vm2": "^3.9.17", + "vm2": "^3.9.18", "winston": "^3.2.1", "yaml": "^2.0.0", "zen-observable": "^0.10.0", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts index 1cce7d66cb..bed15f2e39 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts @@ -46,179 +46,249 @@ describe('catalog:fetch', () => { jest.resetAllMocks(); }); - it('should return entity from catalog', async () => { - getEntityByRef.mockReturnValueOnce({ - metadata: { - namespace: 'default', - name: 'test', - }, - kind: 'Component', - } as Entity); - - await action.handler({ - ...mockContext, - input: { - entityRef: 'component:default/test', - }, - }); - - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', - }); - expect(mockContext.output).toHaveBeenCalledWith('entity', { - metadata: { - namespace: 'default', - name: 'test', - }, - kind: 'Component', - }); - }); - - it('should throw error if entity fetch fails from catalog and optional is false', async () => { - getEntityByRef.mockImplementationOnce(() => { - throw new Error('Not found'); - }); - - await expect( - action.handler({ - ...mockContext, - input: { - entityRef: 'component:default/test', - }, - }), - ).rejects.toThrow('Not found'); - - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', - }); - expect(mockContext.output).not.toHaveBeenCalled(); - }); - - it('should throw error if entity not in catalog and optional is false', async () => { - getEntityByRef.mockReturnValueOnce(null); - - await expect( - action.handler({ - ...mockContext, - input: { - entityRef: 'component:default/test', - }, - }), - ).rejects.toThrow('Entity component:default/test not found'); - - expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', - }); - expect(mockContext.output).not.toHaveBeenCalled(); - }); - - it('should return entities from catalog', async () => { - getEntitiesByRefs.mockReturnValueOnce({ - items: [ - { - metadata: { - namespace: 'default', - name: 'test', - }, - kind: 'Component', - } as Entity, - ], - }); - - await action.handler({ - ...mockContext, - input: { - entityRefs: ['component:default/test'], - }, - }); - - expect(getEntitiesByRefs).toHaveBeenCalledWith( - { entityRefs: ['component:default/test'] }, - { - token: 'secret', - }, - ); - expect(mockContext.output).toHaveBeenCalledWith('entities', [ - { + describe('fetch single entity', () => { + it('should return entity from catalog', async () => { + getEntityByRef.mockReturnValueOnce({ metadata: { namespace: 'default', name: 'test', }, kind: 'Component', - }, - ]); + } as Entity); + + await action.handler({ + ...mockContext, + input: { + entityRef: 'component:default/test', + }, + }); + + expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { + token: 'secret', + }); + expect(mockContext.output).toHaveBeenCalledWith('entity', { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + }); + }); + + it('should throw error if entity fetch fails from catalog and optional is false', async () => { + getEntityByRef.mockImplementationOnce(() => { + throw new Error('Not found'); + }); + + await expect( + action.handler({ + ...mockContext, + input: { + entityRef: 'component:default/test', + }, + }), + ).rejects.toThrow('Not found'); + + expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { + token: 'secret', + }); + expect(mockContext.output).not.toHaveBeenCalled(); + }); + + it('should throw error if entity not in catalog and optional is false', async () => { + getEntityByRef.mockReturnValueOnce(null); + + await expect( + action.handler({ + ...mockContext, + input: { + entityRef: 'component:default/test', + }, + }), + ).rejects.toThrow('Entity component:default/test not found'); + + expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { + token: 'secret', + }); + expect(mockContext.output).not.toHaveBeenCalled(); + }); + + it('should use defaultKind and defaultNamespace if provided', async () => { + const entity: Entity = { + metadata: { + namespace: 'ns', + name: 'test', + }, + kind: 'Group', + } as Entity; + getEntityByRef.mockReturnValueOnce(entity); + + await action.handler({ + ...mockContext, + input: { + entityRef: 'test', + defaultKind: 'Group', + defaultNamespace: 'ns', + }, + }); + + expect(getEntityByRef).toHaveBeenCalledWith('group:ns/test', { + token: 'secret', + }); + expect(mockContext.output).toHaveBeenCalledWith('entity', entity); + }); }); - it('should throw error if undefined is returned for some entity', async () => { - getEntitiesByRefs.mockReturnValueOnce({ - items: [ + describe('fetch multiple entities', () => { + it('should return entities from catalog', async () => { + getEntitiesByRefs.mockReturnValueOnce({ + items: [ + { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + } as Entity, + ], + }); + + await action.handler({ + ...mockContext, + input: { + entityRefs: ['component:default/test'], + }, + }); + + expect(getEntitiesByRefs).toHaveBeenCalledWith( + { entityRefs: ['component:default/test'] }, + { + token: 'secret', + }, + ); + expect(mockContext.output).toHaveBeenCalledWith('entities', [ { metadata: { namespace: 'default', name: 'test', }, kind: 'Component', - } as Entity, - undefined, - ], + }, + ]); }); - await expect( - action.handler({ + it('should throw error if undefined is returned for some entity', async () => { + getEntitiesByRefs.mockReturnValueOnce({ + items: [ + { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + } as Entity, + undefined, + ], + }); + + await expect( + action.handler({ + ...mockContext, + input: { + entityRefs: ['component:default/test', 'component:default/test2'], + optional: false, + }, + }), + ).rejects.toThrow('Entity component:default/test2 not found'); + + expect(getEntitiesByRefs).toHaveBeenCalledWith( + { entityRefs: ['component:default/test', 'component:default/test2'] }, + { + token: 'secret', + }, + ); + expect(mockContext.output).not.toHaveBeenCalled(); + }); + + it('should return null in case some of the entities not found and optional is true', async () => { + getEntitiesByRefs.mockReturnValueOnce({ + items: [ + { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + } as Entity, + undefined, + ], + }); + + await action.handler({ ...mockContext, input: { entityRefs: ['component:default/test', 'component:default/test2'], - optional: false, + optional: true, }, - }), - ).rejects.toThrow('Entity component:default/test2 not found'); + }); - expect(getEntitiesByRefs).toHaveBeenCalledWith( - { entityRefs: ['component:default/test', 'component:default/test2'] }, - { - token: 'secret', - }, - ); - expect(mockContext.output).not.toHaveBeenCalled(); - }); - - it('should return null in case some of the entities not found and optional is true', async () => { - getEntitiesByRefs.mockReturnValueOnce({ - items: [ + expect(getEntitiesByRefs).toHaveBeenCalledWith( + { entityRefs: ['component:default/test', 'component:default/test2'] }, + { + token: 'secret', + }, + ); + expect(mockContext.output).toHaveBeenCalledWith('entities', [ { metadata: { namespace: 'default', name: 'test', }, kind: 'Component', - } as Entity, - undefined, - ], + }, + null, + ]); }); - await action.handler({ - ...mockContext, - input: { - entityRefs: ['component:default/test', 'component:default/test2'], - optional: true, - }, - }); - - expect(getEntitiesByRefs).toHaveBeenCalledWith( - { entityRefs: ['component:default/test', 'component:default/test2'] }, - { - token: 'secret', - }, - ); - expect(mockContext.output).toHaveBeenCalledWith('entities', [ - { + it('should use defaultKind and defaultNamespace if provided', async () => { + const entity1: Entity = { + metadata: { + namespace: 'ns', + name: 'test', + }, + kind: 'Group', + } as Entity; + const entity2: Entity = { metadata: { namespace: 'default', name: 'test', }, - kind: 'Component', - }, - null, - ]); + kind: 'User', + } as Entity; + getEntitiesByRefs.mockReturnValueOnce({ + items: [entity1, entity2], + }); + + await action.handler({ + ...mockContext, + input: { + entityRefs: ['test', 'user:default/test'], + defaultKind: 'Group', + defaultNamespace: 'ns', + }, + }); + + expect(getEntitiesByRefs).toHaveBeenCalledWith( + { entityRefs: ['group:ns/test', 'user:default/test'] }, + { + token: 'secret', + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('entities', [ + entity1, + entity2, + ]); + }); }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts index d6abeee792..437da8ae73 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts @@ -18,6 +18,7 @@ import { CatalogApi } from '@backstage/catalog-client'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import yaml from 'yaml'; import { z } from 'zod'; +import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; const id = 'catalog:fetch'; @@ -69,6 +70,7 @@ export function createFetchCatalogEntityAction(options: { description: 'Returns entity or entities from the catalog by entity reference(s)', examples, + supportsDryRun: true, schema: { input: z.object({ entityRef: z @@ -87,6 +89,10 @@ export function createFetchCatalogEntityAction(options: { 'Allow the entity or entities to optionally exist. Default: false', }) .optional(), + defaultKind: z.string({ description: 'The default kind' }).optional(), + defaultNamespace: z + .string({ description: 'The default namespace' }) + .optional(), }), output: z.object({ entity: z @@ -106,7 +112,8 @@ export function createFetchCatalogEntityAction(options: { }), }, async handler(ctx) { - const { entityRef, entityRefs, optional } = ctx.input; + const { entityRef, entityRefs, optional, defaultKind, defaultNamespace } = + ctx.input; if (!entityRef && !entityRefs) { if (optional) { return; @@ -115,9 +122,14 @@ export function createFetchCatalogEntityAction(options: { } if (entityRef) { - const entity = await catalogClient.getEntityByRef(entityRef, { - token: ctx.secrets?.backstageToken, - }); + const entity = await catalogClient.getEntityByRef( + stringifyEntityRef( + parseEntityRef(entityRef, { defaultKind, defaultNamespace }), + ), + { + token: ctx.secrets?.backstageToken, + }, + ); if (!entity && !optional) { throw new Error(`Entity ${entityRef} not found`); @@ -127,7 +139,13 @@ export function createFetchCatalogEntityAction(options: { if (entityRefs) { const entities = await catalogClient.getEntitiesByRefs( - { entityRefs }, + { + entityRefs: entityRefs.map(ref => + stringifyEntityRef( + parseEntityRef(ref, { defaultKind, defaultNamespace }), + ), + ), + }, { token: ctx.secrets?.backstageToken, }, diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index deff4392d6..1771067367 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -36,8 +36,10 @@ import { TemplateEntityStepV1beta3, } from '@backstage/plugin-scaffolder-common'; import { + RESOURCE_TYPE_SCAFFOLDER_ACTION, RESOURCE_TYPE_SCAFFOLDER_TEMPLATE, - scaffolderPermissions, + scaffolderActionPermissions, + scaffolderTemplatePermissions, templateParameterReadPermission, templateStepReadPermission, } from '@backstage/plugin-scaffolder-common/alpha'; @@ -71,7 +73,7 @@ import { createPermissionIntegrationRouter, PermissionRule, } from '@backstage/plugin-permission-node'; -import { scaffolderTemplateRules } from './rules'; +import { scaffolderActionRules, scaffolderTemplateRules } from './rules'; /** * @@ -85,6 +87,29 @@ export type TemplatePermissionRuleInput< typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE, TParams >; +function isTemplatePermissionRuleInput( + permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput, +): permissionRule is TemplatePermissionRuleInput { + return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_TEMPLATE; +} + +/** + * + * @public + */ +export type ActionPermissionRuleInput< + TParams extends PermissionRuleParams = PermissionRuleParams, +> = PermissionRule< + TemplateEntityStepV1beta3 | TemplateParametersV1beta3, + {}, + typeof RESOURCE_TYPE_SCAFFOLDER_ACTION, + TParams +>; +function isActionPermissionRuleInput( + permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput, +): permissionRule is ActionPermissionRuleInput { + return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_ACTION; +} /** * RouterOptions @@ -113,7 +138,9 @@ export interface RouterOptions { additionalTemplateFilters?: Record; additionalTemplateGlobals?: Record; permissions?: PermissionEvaluator; - permissionRules?: TemplatePermissionRuleInput[]; + permissionRules?: Array< + TemplatePermissionRuleInput | ActionPermissionRuleInput + >; identity?: IdentityApi; } @@ -290,17 +317,32 @@ export async function createRouter( const templateRules: TemplatePermissionRuleInput[] = Object.values( scaffolderTemplateRules, ); + const actionRules: ActionPermissionRuleInput[] = Object.values( + scaffolderActionRules, + ); if (permissionRules) { - templateRules.push(...permissionRules); + templateRules.push( + ...permissionRules.filter(isTemplatePermissionRuleInput), + ); + actionRules.push(...permissionRules.filter(isActionPermissionRuleInput)); } const isAuthorized = createConditionAuthorizer(Object.values(templateRules)); const permissionIntegrationRouter = createPermissionIntegrationRouter({ - resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE, - permissions: scaffolderPermissions, - rules: templateRules, + resources: [ + { + resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE, + permissions: scaffolderTemplatePermissions, + rules: templateRules, + }, + { + resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION, + permissions: scaffolderActionPermissions, + rules: actionRules, + }, + ], }); router.use(permissionIntegrationRouter); diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index c317230580..b5bcabb64f 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-scaffolder-common +## 1.3.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates +- 67115f532b8: Expose scaffolder permissions in new sub-aggregations. + + In addition to exporting a list of all scaffolder permissions in `scaffolderPermissions`, scaffolder-common now exports `scaffolderTemplatePermissions` and `scaffolderActionPermissions`, which contain subsets of the scaffolder permissions separated by resource type. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + +## 1.3.0-next.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + ## 1.2.7 ### Patch Changes diff --git a/plugins/scaffolder-common/alpha-api-report.md b/plugins/scaffolder-common/alpha-api-report.md index d6e746026a..de9dffd1b9 100644 --- a/plugins/scaffolder-common/alpha-api-report.md +++ b/plugins/scaffolder-common/alpha-api-report.md @@ -14,12 +14,18 @@ export const RESOURCE_TYPE_SCAFFOLDER_ACTION = 'scaffolder-action'; // @alpha export const RESOURCE_TYPE_SCAFFOLDER_TEMPLATE = 'scaffolder-template'; +// @alpha +export const scaffolderActionPermissions: ResourcePermission<'scaffolder-action'>[]; + // @alpha export const scaffolderPermissions: ( | ResourcePermission<'scaffolder-action'> | ResourcePermission<'scaffolder-template'> )[]; +// @alpha +export const scaffolderTemplatePermissions: ResourcePermission<'scaffolder-template'>[]; + // @alpha export const templateParameterReadPermission: ResourcePermission<'scaffolder-template'>; diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 6dfe10121e..45b4986155 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-common", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.2.7", + "version": "1.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-common/src/Template.v1beta3.schema.json b/plugins/scaffolder-common/src/Template.v1beta3.schema.json index beb0ca5e31..1de68205b2 100644 --- a/plugins/scaffolder-common/src/Template.v1beta3.schema.json +++ b/plugins/scaffolder-common/src/Template.v1beta3.schema.json @@ -218,6 +218,33 @@ } } } + }, + "text": { + "type": "array", + "description": "A list of Markdown text blobs, like output data from the template.", + "items": { + "type": "object", + "required": [], + "properties": { + "title": { + "type": "string", + "description": "A user friendly display name for the text.", + "examples": ["Output Content"], + "minLength": 1 + }, + "icon": { + "type": "string", + "description": "A key representing a visual icon to be displayed in the UI.", + "examples": ["dashboard"], + "minLength": 1 + }, + "content": { + "type": "string", + "description": "The text blob to display in the UI, rendered as Markdown.", + "examples": ["**hey** _I'm_ Markdown"] + } + } + } } }, "additionalProperties": { diff --git a/plugins/scaffolder-common/src/permissions.ts b/plugins/scaffolder-common/src/permissions.ts index f06d7984f2..5c4c367889 100644 --- a/plugins/scaffolder-common/src/permissions.ts +++ b/plugins/scaffolder-common/src/permissions.ts @@ -87,3 +87,18 @@ export const scaffolderPermissions = [ templateParameterReadPermission, templateStepReadPermission, ]; + +/** + * List of the scaffolder permissions that are associated with template steps and parameters. + * @alpha + */ +export const scaffolderTemplatePermissions = [ + templateParameterReadPermission, + templateStepReadPermission, +]; + +/** + * List of the scaffolder permissions that are associated with scaffolder actions. + * @alpha + */ +export const scaffolderActionPermissions = [actionExecutePermission]; diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 796c157f7a..7c4f4316ec 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-scaffolder-node +## 0.1.3 + +### Patch Changes + +- 6d954de4b06: Update typing for `RouterOptions::actions` and `ScaffolderActionsExtensionPoint::addActions` to allow any kind of action being assigned to it. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/types@1.0.2 + +## 0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index f1e49a52e1..4eda195f91 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-node", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", - "version": "0.1.3-next.1", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 402c552c79..59434d30cf 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-scaffolder-react +## 1.4.0 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + +### Patch Changes + +- ad1a1429de4: Improvements to the `scaffolder/next` buttons UX: + + - Added padding around the "Create" button in the `Stepper` component + - Added a button bar that includes the "Cancel" and "Start Over" buttons to the `OngoingTask` component. The state of these buttons match their existing counter parts in the Context Menu + - Added a "Show Button Bar"/"Hide Button Bar" item to the `ContextMenu` component + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + +## 1.4.0-next.2 + +### Minor Changes + +- 82e10a6939c: Add support for Markdown text blob outputs from templates + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 1.3.1-next.1 ### Patch Changes diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index baf5afb312..1761c88edf 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -217,6 +217,13 @@ export type ScaffolderOutputLink = { entityRef?: string; }; +// @public (undocumented) +export type ScaffolderOutputText = { + title?: string; + icon?: string; + content?: string; +}; + // @public export interface ScaffolderScaffoldOptions { // (undocumented) @@ -261,6 +268,7 @@ export type ScaffolderTask = { // @public (undocumented) export type ScaffolderTaskOutput = { links?: ScaffolderOutputLink[]; + text?: ScaffolderOutputText[]; } & { [key: string]: unknown; }; diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 571b356a2d..5e5732fb04 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-react", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", - "version": "1.3.1-next.1", + "version": "1.4.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-react/src/api/types.ts b/plugins/scaffolder-react/src/api/types.ts index b39555c14f..2adecdd0d2 100644 --- a/plugins/scaffolder-react/src/api/types.ts +++ b/plugins/scaffolder-react/src/api/types.ts @@ -84,9 +84,17 @@ export type ScaffolderOutputLink = { entityRef?: string; }; +/** @public */ +export type ScaffolderOutputText = { + title?: string; + icon?: string; + content?: string; +}; + /** @public */ export type ScaffolderTaskOutput = { links?: ScaffolderOutputLink[]; + text?: ScaffolderOutputText[]; } & { [key: string]: unknown; }; diff --git a/plugins/scaffolder-react/src/hooks/useEventStream.ts b/plugins/scaffolder-react/src/hooks/useEventStream.ts index ec49911471..ad802dba99 100644 --- a/plugins/scaffolder-react/src/hooks/useEventStream.ts +++ b/plugins/scaffolder-react/src/hooks/useEventStream.ts @@ -169,67 +169,85 @@ export const useTaskEventStream = (taskId: string): TaskStream => { let didCancel = false; let subscription: Subscription | undefined; let logPusher: NodeJS.Timeout | undefined; - - scaffolderApi.getTask(taskId).then( - task => { - if (didCancel) { - return; - } - dispatch({ type: 'INIT', data: task }); - - // TODO(blam): Use a normal fetch to fetch the current log for the event stream - // and use that for an INIT_EVENTs dispatch event, and then - // use the last event ID to subscribe using after option to - // stream logs. Without this, if you have a lot of logs, it can look like the - // task is being rebuilt on load as it progresses through the steps at a slower - // rate whilst it builds the status from the event logs - const observable = scaffolderApi.streamLogs({ taskId }); - - const collectedLogEvents = new Array(); - - function emitLogs() { - if (collectedLogEvents.length) { - const logs = collectedLogEvents.splice( - 0, - collectedLogEvents.length, - ); - dispatch({ type: 'LOGS', data: logs }); + let retryCount = 1; + const startStreamLogProcess = () => + scaffolderApi.getTask(taskId).then( + task => { + if (didCancel) { + return; } - } + dispatch({ type: 'INIT', data: task }); - logPusher = setInterval(emitLogs, 500); + // TODO(blam): Use a normal fetch to fetch the current log for the event stream + // and use that for an INIT_EVENTs dispatch event, and then + // use the last event ID to subscribe using after option to + // stream logs. Without this, if you have a lot of logs, it can look like the + // task is being rebuilt on load as it progresses through the steps at a slower + // rate whilst it builds the status from the event logs + const observable = scaffolderApi.streamLogs({ taskId }); - subscription = observable.subscribe({ - next: event => { - switch (event.type) { - case 'log': - return collectedLogEvents.push(event); - case 'cancelled': - dispatch({ type: 'CANCELLED' }); - return undefined; - case 'completion': - emitLogs(); - dispatch({ type: 'COMPLETED', data: event }); - return undefined; - default: - throw new Error( - `Unhandled event type ${event.type} in observer`, - ); + const collectedLogEvents = new Array(); + + function emitLogs() { + if (collectedLogEvents.length) { + const logs = collectedLogEvents.splice( + 0, + collectedLogEvents.length, + ); + dispatch({ type: 'LOGS', data: logs }); } - }, - error: error => { - emitLogs(); - dispatch({ type: 'ERROR', data: error }); - }, - }); - }, - error => { - if (!didCancel) { - dispatch({ type: 'ERROR', data: error }); - } - }, - ); + } + logPusher = setInterval(emitLogs, 500); + + subscription = observable.subscribe({ + next: event => { + switch (event.type) { + case 'log': + return collectedLogEvents.push(event); + case 'cancelled': + dispatch({ type: 'CANCELLED' }); + return undefined; + case 'completion': + emitLogs(); + dispatch({ type: 'COMPLETED', data: event }); + return undefined; + default: + throw new Error( + `Unhandled event type ${event.type} in observer`, + ); + } + }, + error: error => { + emitLogs(); + // in some cases the error is a refused connection from backend + // this can happen from internet issues or proxy problems + // so we try to reconnect again after some time + // just to restart the fetch process + // details here https://github.com/backstage/backstage/issues/15002 + + if (!error.message) { + error.message = `We cannot connect at the moment, trying again in some seconds... Retrying (${retryCount}/3 retries)`; + } + + if (retryCount <= 3) { + setTimeout(() => { + retryCount += 1; + startStreamLogProcess(); + }, 15000); + } + + dispatch({ type: 'ERROR', data: error }); + }, + }); + }, + error => { + if (!didCancel) { + dispatch({ type: 'ERROR', data: error }); + } + }, + ); + startStreamLogProcess(); return () => { didCancel = true; if (subscription) { diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx new file mode 100644 index 0000000000..8366dcadf8 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.test.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2022 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 { entityRouteRef } from '@backstage/plugin-catalog-react'; +import { renderInTestApp } from '@backstage/test-utils'; +import { fireEvent } from '@testing-library/react'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { DefaultTemplateOutputs } from '.'; + +describe('', () => { + it('should render template output', async () => { + const output = { + links: [{ title: 'Link 1', url: 'https://backstage.io/' }], + text: [{ title: 'Text 1', content: 'Hello, **world**!' }], + }; + + const { getByRole } = await renderInTestApp( + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + // test link outputs + for (const link of output.links ?? []) { + expect( + getByRole('button', { name: link.title }).closest('a'), + ).toHaveAttribute('href', link.url); + } + + // test text outputs + for (const text of output.text ?? []) { + await act(async () => { + fireEvent.click(getByRole('button', { name: text.title })); + }); + + expect(getByRole('heading', { level: 2 }).innerHTML).toBe(text.title); + } + }); +}); diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx index 4d908461b0..a495e4ca9e 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; -import { Box, Paper } from '@material-ui/core'; -import { LinkOutputs } from './LinkOutputs'; +import { InfoCard, MarkdownContent } from '@backstage/core-components'; import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; +import { Box, Paper } from '@material-ui/core'; +import React, { useMemo, useState } from 'react'; +import { LinkOutputs } from './LinkOutputs'; +import { TextOutputs } from './TextOutputs'; /** * The DefaultOutputs renderer for the scaffolder task output @@ -26,17 +28,47 @@ import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; export const DefaultTemplateOutputs = (props: { output?: ScaffolderTaskOutput; }) => { - if (!props.output?.links) { + const [textOutputIndex, setTextOutputIndex] = useState(); + + const textOutput = useMemo( + () => + textOutputIndex !== undefined + ? props.output?.text?.[textOutputIndex] + : null, + [props.output, textOutputIndex], + ); + + if (!props.output) { return null; } return ( - - - - + <> + + + + + + + + + {textOutput ? ( + + + + + + - - + ) : null} + ); }; diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx new file mode 100644 index 0000000000..7e64603e92 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/TextOutputs.tsx @@ -0,0 +1,59 @@ +/* + * Copyright 2023 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 { IconComponent, useApp } from '@backstage/core-plugin-api'; +import { Button } from '@material-ui/core'; +import WebIcon from '@material-ui/icons/Web'; +import React from 'react'; +import { ScaffolderTaskOutput } from '../../../api'; + +export const TextOutputs = (props: { + output: ScaffolderTaskOutput; + index?: number; + setIndex?: (index: number | undefined) => void; +}) => { + const { + output: { text = [] }, + index, + setIndex, + } = props; + + const app = useApp(); + + const iconResolver = (key?: string): IconComponent => + app.getSystemIcon(key!) ?? WebIcon; + + return ( + <> + {text + .filter(({ content }) => content !== undefined) + .map(({ title, icon }, i) => { + const Icon = iconResolver(icon); + return ( + + ); + })} + + ); +}; diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 11cc2224aa..9658bfc48f 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-scaffolder +## 1.13.1 + +### Patch Changes + +- d560d457c98: Fix case GitLab workspace is a nested subgroup +- ad1a1429de4: Improvements to the `scaffolder/next` buttons UX: + + - Added padding around the "Create" button in the `Stepper` component + - Added a button bar that includes the "Cancel" and "Start Over" buttons to the `OngoingTask` component. The state of these buttons match their existing counter parts in the Context Menu + - Added a "Show Button Bar"/"Hide Button Bar" item to the `ContextMenu` component + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-scaffolder-common@1.3.0 + - @backstage/plugin-scaffolder-react@1.4.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-react@0.4.12 + +## 1.13.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/plugin-scaffolder-common@1.3.0-next.0 + - @backstage/plugin-scaffolder-react@1.4.0-next.2 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-permission-react@0.4.12 + ## 1.13.1-next.1 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 2d618d6960..ce2032a1cc 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.13.1-next.1", + "version": "1.13.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -74,6 +74,7 @@ "@types/react": "^16.13.1 || ^17.0.0", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", + "event-source-polyfill": "^1.0.31", "git-url-parse": "^13.0.0", "humanize-duration": "^3.25.1", "immer": "^9.0.1", @@ -108,7 +109,6 @@ "@types/json-schema": "^7.0.9", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "event-source-polyfill": "1.0.25", "msw": "^1.0.0" }, "files": [ diff --git a/plugins/scaffolder/src/api.test.ts b/plugins/scaffolder/src/api.test.ts index e21bda8fd7..b9b1881066 100644 --- a/plugins/scaffolder/src/api.test.ts +++ b/plugins/scaffolder/src/api.test.ts @@ -20,11 +20,14 @@ import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { ScaffolderClient } from './api'; +import { EventSourcePolyfill } from 'event-source-polyfill'; -const MockedEventSource = global.EventSource as jest.MockedClass< - typeof EventSource +const MockedEventSource = EventSourcePolyfill as jest.MockedClass< + typeof EventSourcePolyfill >; +jest.mock('event-source-polyfill'); + const server = setupServer(); describe('api', () => { @@ -102,6 +105,9 @@ describe('api', () => { }, ); + const token = 'fake-token'; + identityApi.getCredentials.mockResolvedValue({ token: token }); + const next = jest.fn(); await new Promise(complete => { @@ -112,7 +118,10 @@ describe('api', () => { expect(MockedEventSource).toHaveBeenCalledWith( 'http://backstage/api/v2/tasks/a-random-task-id/eventstream', - { withCredentials: true }, + { + withCredentials: true, + headers: { Authorization: `Bearer ${token}` }, + }, ); expect(MockedEventSource.prototype.close).toHaveBeenCalled(); diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 7a3f6c14bb..c67a5c944e 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -41,6 +41,7 @@ import { } from '@backstage/plugin-scaffolder-react'; import queryString from 'qs'; +import { EventSourcePolyfill } from 'event-source-polyfill'; /** * An API to interact with the scaffolder backend. @@ -224,8 +225,11 @@ export class ScaffolderClient implements ScaffolderApi { params.set('after', String(Number(after))); } - this.discoveryApi.getBaseUrl('scaffolder').then( - baseUrl => { + Promise.all([ + this.discoveryApi.getBaseUrl('scaffolder'), + this.identityApi?.getCredentials(), + ]).then( + ([baseUrl, credentials]) => { const url = `${baseUrl}/v2/tasks/${encodeURIComponent( taskId, )}/eventstream`; @@ -240,7 +244,12 @@ export class ScaffolderClient implements ScaffolderApi { } }; - const eventSource = new EventSource(url, { withCredentials: true }); + const eventSource = new EventSourcePolyfill(url, { + withCredentials: true, + headers: credentials?.token + ? { Authorization: `Bearer ${credentials.token}` } + : {}, + }); eventSource.addEventListener('log', processEvent); eventSource.addEventListener('cancelled', processEvent); eventSource.addEventListener('completion', (event: any) => { diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index bf64047538..f8c7e04d44 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index 15421990e2..8e0e30d711 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-catalog", "description": "A module for the search backend that exports catalog modules", - "version": "0.1.1-next.1", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index f5c5d9acd5..e699ee60c7 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.3.0 + +### Minor Changes + +- 3d72bdb41c7: Upgrade to aws-sdk v3 and include OpenSearch Serverless support + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + +## 1.3.0-next.2 + +### Minor Changes + +- 3d72bdb41c7: Upgrade to aws-sdk v3 and include OpenSearch Serverless support + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/integration-aws-node@0.1.2 + ## 1.2.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/api-report.md b/plugins/search-backend-module-elasticsearch/api-report.md index c7add1e8cb..b567414b22 100644 --- a/plugins/search-backend-module-elasticsearch/api-report.md +++ b/plugins/search-backend-module-elasticsearch/api-report.md @@ -8,8 +8,8 @@ import { ApiResponse } from '@opensearch-project/opensearch'; import { ApiResponse as ApiResponse_2 } from '@elastic/elasticsearch'; import { BatchSearchEngineIndexer } from '@backstage/plugin-search-backend-node'; -import { BulkHelper } from '@opensearch-project/opensearch/lib/Helpers'; -import { BulkStats } from '@opensearch-project/opensearch/lib/Helpers'; +import { BulkHelper } from '@elastic/elasticsearch/lib/Helpers'; +import { BulkStats } from '@elastic/elasticsearch/lib/Helpers'; import { Config } from '@backstage/config'; import type { ConnectionOptions } from 'tls'; import { IndexableDocument } from '@backstage/plugin-search-common'; @@ -424,6 +424,10 @@ export interface OpenSearchElasticSearchClientOptions nodes?: string | string[] | OpenSearchNodeOptions | OpenSearchNodeOptions[]; // (undocumented) provider?: 'aws' | 'opensearch'; + // (undocumented) + region?: string; + // (undocumented) + service?: 'es' | 'aoss'; } // @public (undocumented) diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 73c3a5d7dc..e8d999e840 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.2.1-next.1", + "version": "1.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -39,12 +39,12 @@ "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", + "@backstage/integration-aws-node": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@elastic/elasticsearch": "^7.13.0", - "@opensearch-project/opensearch": "^2.0.0", - "aws-os-connection": "^0.2.0", - "aws-sdk": "^2.948.0", + "@opensearch-project/opensearch": "^2.2.1", + "aws4": "^1.12.0", "elastic-builder": "^2.16.0", "lodash": "^4.17.21", "uuid": "^8.3.2", diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientOptions.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientOptions.ts index 8cb2f67fce..2974f03331 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientOptions.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientOptions.ts @@ -51,6 +51,8 @@ export type ElasticSearchClientOptions = export interface OpenSearchElasticSearchClientOptions extends BaseElasticSearchClientOptions { provider?: 'aws' | 'opensearch'; + region?: string; + service?: 'es' | 'aoss'; auth?: OpenSearchAuth; connection?: OpenSearchConnectionConstructor; node?: string | string[] | OpenSearchNodeOptions | OpenSearchNodeOptions[]; diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientWrapper.test.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientWrapper.test.ts index 7355daf3b9..75f2e36b2b 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientWrapper.test.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchClientWrapper.test.ts @@ -14,17 +14,13 @@ * limitations under the License. */ -import { ConfigReader } from '@backstage/config'; import { Client as ElasticSearchClient } from '@elastic/elasticsearch'; import { Client as OpenSearchClient } from '@opensearch-project/opensearch'; import Mock from '@short.io/opensearch-mock'; import { Readable } from 'stream'; import { ElasticSearchClientWrapper } from './ElasticSearchClientWrapper'; -import { - createElasticSearchClientOptions, - ElasticSearchClientOptions, -} from './ElasticSearchSearchEngine'; +import { ElasticSearchClientOptions } from './ElasticSearchSearchEngine'; jest.mock('@elastic/elasticsearch', () => ({ ...jest.requireActual('@elastic/elasticsearch'), @@ -103,11 +99,9 @@ describe('ElasticSearchClientWrapper', () => { let esOptions: ElasticSearchClientOptions; beforeEach(async () => { - esOptions = await createElasticSearchClientOptions( - new ConfigReader({ - node: 'http://localhost:9200', - }), - ); + esOptions = { + node: 'http://localhost:9200', + }; jest.clearAllMocks(); }); @@ -229,6 +223,7 @@ describe('ElasticSearchClientWrapper', () => { osOptions = { provider: 'aws', node: 'https://my-es-cluster.eu-west-1.es.amazonaws.com', + region: 'eu-west-1', // todo(backstage/techdocs-core): Remove the following ts-ignore when // @short.io/opensearch-mock is updated to work w/opensearch >= 2.0.0 // @ts-ignore diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index 3294ca9d33..90f6f407d9 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -21,9 +21,10 @@ import { SearchEngine, SearchQuery, } from '@backstage/plugin-search-common'; -import { awsGetCredentials, createAWSConnection } from 'aws-os-connection'; import { isEmpty, isNumber, isNaN as nan } from 'lodash'; +import { AwsSigv4Signer } from '@opensearch-project/opensearch/aws'; +import { RequestSigner } from 'aws4'; import { Config } from '@backstage/config'; import { ElasticSearchClientOptions } from './ElasticSearchClientOptions'; import { ElasticSearchClientWrapper } from './ElasticSearchClientWrapper'; @@ -33,6 +34,10 @@ import { Logger } from 'winston'; import { MissingIndexError } from '@backstage/plugin-search-backend-node'; import esb from 'elastic-builder'; import { v4 as uuid } from 'uuid'; +import { + AwsCredentialProvider, + DefaultAwsCredentialsManager, +} from '@backstage/integration-aws-node'; export type { ElasticSearchClientOptions }; @@ -145,8 +150,9 @@ export class ElasticSearchSearchEngine implements SearchEngine { aliasPostfix = `search`, indexPrefix = ``, } = options; - - const clientOptions = await createElasticSearchClientOptions( + const credentialProvider = DefaultAwsCredentialsManager.fromConfig(config); + const clientOptions = await this.createElasticSearchClientOptions( + await credentialProvider?.getCredentialProvider(), config.getConfig('search.elasticsearch'), ); if (clientOptions.provider === 'elastic') { @@ -412,6 +418,106 @@ export class ElasticSearchSearchEngine implements SearchEngine { const postFix = this.aliasPostfix ? `__${this.aliasPostfix}` : ''; return `${this.indexPrefix}${type}${postFix}`; } + + private static async createElasticSearchClientOptions( + credentialProvider: AwsCredentialProvider, + config?: Config, + ): Promise { + if (!config) { + throw new Error('No elastic search config found'); + } + const clientOptionsConfig = config.getOptionalConfig('clientOptions'); + const sslConfig = clientOptionsConfig?.getOptionalConfig('ssl'); + + if (config.getOptionalString('provider') === 'elastic') { + const authConfig = config.getConfig('auth'); + return { + provider: 'elastic', + cloud: { + id: config.getString('cloudId'), + }, + auth: { + username: authConfig.getString('username'), + password: authConfig.getString('password'), + }, + ...(sslConfig + ? { + ssl: { + rejectUnauthorized: + sslConfig?.getOptionalBoolean('rejectUnauthorized'), + }, + } + : {}), + }; + } + if (config.getOptionalString('provider') === 'aws') { + const requestSigner = new RequestSigner(config.getString('node')); + const service = + config.getOptionalString('service') ?? requestSigner.service; + if (service !== 'es' && service !== 'aoss') + throw new Error(`Unrecognized serivce type: ${service}`); + return { + provider: 'aws', + node: config.getString('node'), + ...(sslConfig + ? { + ssl: { + rejectUnauthorized: + sslConfig?.getOptionalBoolean('rejectUnauthorized'), + }, + } + : {}), + ...AwsSigv4Signer({ + region: config.getOptionalString('region') ?? requestSigner.region, // for backwards compatibility + service: service, + getCredentials: async () => + await credentialProvider.sdkCredentialProvider(), + }), + }; + } + if (config.getOptionalString('provider') === 'opensearch') { + const authConfig = config.getConfig('auth'); + return { + provider: 'opensearch', + node: config.getString('node'), + auth: { + username: authConfig.getString('username'), + password: authConfig.getString('password'), + }, + ...(sslConfig + ? { + ssl: { + rejectUnauthorized: + sslConfig?.getOptionalBoolean('rejectUnauthorized'), + }, + } + : {}), + }; + } + const authConfig = config.getOptionalConfig('auth'); + const auth = + authConfig && + (authConfig.has('apiKey') + ? { + apiKey: authConfig.getString('apiKey'), + } + : { + username: authConfig.getString('username'), + password: authConfig.getString('password'), + }); + return { + node: config.getString('node'), + auth, + ...(sslConfig + ? { + ssl: { + rejectUnauthorized: + sslConfig?.getOptionalBoolean('rejectUnauthorized'), + }, + } + : {}), + }; + } } /** @@ -430,97 +536,3 @@ export function decodePageCursor(pageCursor?: string): { page: number } { export function encodePageCursor({ page }: { page: number }): string { return Buffer.from(`${page}`, 'utf-8').toString('base64'); } - -export async function createElasticSearchClientOptions( - config?: Config, -): Promise { - if (!config) { - throw new Error('No elastic search config found'); - } - const clientOptionsConfig = config.getOptionalConfig('clientOptions'); - const sslConfig = clientOptionsConfig?.getOptionalConfig('ssl'); - - if (config.getOptionalString('provider') === 'elastic') { - const authConfig = config.getConfig('auth'); - return { - provider: 'elastic', - cloud: { - id: config.getString('cloudId'), - }, - auth: { - username: authConfig.getString('username'), - password: authConfig.getString('password'), - }, - ...(sslConfig - ? { - ssl: { - rejectUnauthorized: - sslConfig?.getOptionalBoolean('rejectUnauthorized'), - }, - } - : {}), - }; - } - if (config.getOptionalString('provider') === 'aws') { - const awsCredentials = await awsGetCredentials(); - const AWSConnection = createAWSConnection(awsCredentials); - return { - provider: 'aws', - // todo(backstage/techdocs-core): Remove the following ts-ignore when - // aws-os-connection is updated to work with opensearch >= 2.0.0 - // @ts-ignore - node: config.getString('node'), - ...AWSConnection, - ...(sslConfig - ? { - ssl: { - rejectUnauthorized: - sslConfig?.getOptionalBoolean('rejectUnauthorized'), - }, - } - : {}), - }; - } - if (config.getOptionalString('provider') === 'opensearch') { - const authConfig = config.getConfig('auth'); - return { - provider: 'opensearch', - node: config.getString('node'), - auth: { - username: authConfig.getString('username'), - password: authConfig.getString('password'), - }, - ...(sslConfig - ? { - ssl: { - rejectUnauthorized: - sslConfig?.getOptionalBoolean('rejectUnauthorized'), - }, - } - : {}), - }; - } - const authConfig = config.getOptionalConfig('auth'); - const auth = - authConfig && - (authConfig.has('apiKey') - ? { - apiKey: authConfig.getString('apiKey'), - } - : { - username: authConfig.getString('username'), - password: authConfig.getString('password'), - }); - return { - node: config.getString('node'), - auth, - ...(sslConfig - ? { - ssl: { - rejectUnauthorized: - sslConfig?.getOptionalBoolean('rejectUnauthorized'), - }, - } - : {}), - }; -} diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index df693832db..529cdcc99e 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 00f63ef41e..6a6f92a9cc 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-explore", "description": "A module for the search backend that exports explore modules", - "version": "0.1.1-next.1", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 9b9ddfa0ff..98354dd3ea 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + ## 0.5.6-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 5d63d913e0..e623ba034d 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.5.6-next.1", + "version": "0.5.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 83eed95d8e..fe6fc1420d 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index f7d7151aeb..b45a7a3b66 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", "description": "A module for the search backend that exports techdocs modules", - "version": "0.1.1-next.1", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 00a828f132..7aca52d696 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-search-backend-node +## 1.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + ## 1.2.1-next.1 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 9d7b0b0210..21a38cf3b5 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.2.1-next.1", + "version": "1.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 321fdefbc1..5bbc969216 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-search-backend +## 1.3.1 + +### Patch Changes + +- 021cfbb5152: Added an OpenAPI 3.0 spec and enforced schema-first model on the router. +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-permission-node@0.7.8 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/plugin-search-backend-node@1.2.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.3.1-next.2 + +### Patch Changes + +- 021cfbb5152: Added an OpenAPI 3.0 spec and enforced schema-first model on the router. +- Updated dependencies + - @backstage/config@1.0.7 + ## 1.3.1-next.1 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index d3648c33bf..c7658ab754 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.3.1-next.1", + "version": "1.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 569e66eaba..6527d67bb9 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-search-react +## 1.6.0 + +### Minor Changes + +- 750e45539ad: Add close button & improve search input. + + MUI's Paper wrapping the SearchBar in the SearchPage was removed, we recommend users update their apps accordingly. + + SearchBarBase's TextField's label support added & aria-label uses label string if present, tests relying on the default placeholder value should still work unless custom placeholder was given. + +- 1ce7f84b2e8: accepts InputProp property that can override keys from default + +### Patch Changes + +- f785f0804cd: `SearchPagination` now automatically resets the page cursor when the page limit is changed +- adb31096bc2: Fix text-overflow UI issue for Lifecycle spans in SearchFilter checkbox labels. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.0-next.2 + +### Minor Changes + +- 1ce7f84b2e8: accepts InputProp property that can override keys from default + +### Patch Changes + +- adb31096bc2: Fix text-overflow UI issue for Lifecycle spans in SearchFilter checkbox labels. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 1.6.0-next.1 ### Patch Changes diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md index e39e91de72..8afde8c4a5 100644 --- a/plugins/search-react/api-report.md +++ b/plugins/search-react/api-report.md @@ -260,7 +260,7 @@ export type SearchPaginationLimitText = (params: { export type SearchPaginationProps = Omit< SearchPaginationBaseProps, | 'pageLimit' - | 'onPageLimitChange' + | 'onLimitChange' | 'pageCursor' | 'onPageCursorChange' | 'hasNextPage' diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 2467c60b09..6a5b326f34 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.6.0-next.1", + "version": "1.6.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx index 559ae1776e..7e97d790a7 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx @@ -92,13 +92,18 @@ const useStyles = makeStyles({ borderRadius: '50px', margin: 'auto', }, + notchedOutline: { + borderStyle: 'none', + }, }); export const CustomStyles = () => { const classes = useStyles(); return ( - + ); }; diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.tsx index 913f515aaa..cfd0538694 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.tsx @@ -80,7 +80,8 @@ export const SearchBarBase: ForwardRefExoticComponent = value: defaultValue, label, placeholder, - inputProps: defaultInputProps = {}, + inputProps = {}, + InputProps = {}, endAdornment, ...rest } = props; @@ -168,10 +169,11 @@ export const SearchBarBase: ForwardRefExoticComponent = endAdornment: clearButton ? clearButtonEndAdornment : endAdornment, + ...InputProps, }} inputProps={{ 'aria-label': ariaLabel, - ...defaultInputProps, + ...inputProps, }} fullWidth={fullWidth} onChange={handleChange} diff --git a/plugins/search-react/src/components/SearchPagination/SearchPagination.test.tsx b/plugins/search-react/src/components/SearchPagination/SearchPagination.test.tsx index d2ecc55d31..65e65d9436 100644 --- a/plugins/search-react/src/components/SearchPagination/SearchPagination.test.tsx +++ b/plugins/search-react/src/components/SearchPagination/SearchPagination.test.tsx @@ -185,4 +185,31 @@ describe('SearchPagination', () => { }), ); }); + + it('Resets page cursor when page limit changes', async () => { + const initialState = { + term: '', + types: [], + filters: {}, + pageCursor: 'Mg==', // page: 2 + }; + + await renderWithEffects( + + + + + , + ); + + await userEvent.click(screen.getByText('25')); // first click to open the options + await userEvent.click(screen.getByText('10')); // second click to select the option + + expect(query).toHaveBeenLastCalledWith( + expect.objectContaining({ + pageCursor: undefined, + pageLimit: 10, + }), + ); + }); }); diff --git a/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx b/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx index 7ab9e8604c..743d3ccb52 100644 --- a/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx +++ b/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx @@ -176,7 +176,7 @@ export const SearchPaginationBase = (props: SearchPaginationBaseProps) => { export type SearchPaginationProps = Omit< SearchPaginationBaseProps, | 'pageLimit' - | 'onPageLimitChange' + | 'onLimitChange' | 'pageCursor' | 'onPageCursorChange' | 'hasNextPage' @@ -191,12 +191,20 @@ export const SearchPagination = (props: SearchPaginationProps) => { const { pageLimit, setPageLimit, pageCursor, setPageCursor, fetchNextPage } = useSearch(); + const handlePageLimitChange = useCallback( + (newPageLimit: number) => { + setPageLimit(newPageLimit); + setPageCursor(undefined); + }, + [setPageLimit, setPageCursor], + ); + return ( diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index c5209d2859..2427adb905 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-search +## 1.3.0 + +### Minor Changes + +- 750e45539ad: Add close button & improve search input. + + MUI's Paper wrapping the SearchBar in the SearchPage was removed, we recommend users update their apps accordingly. + + SearchBarBase's TextField's label support added & aria-label uses label string if present, tests relying on the default placeholder value should still work unless custom placeholder was given. + +### Patch Changes + +- 0e3d8d69318: Fixed 404 Error when fetching search results due to URL encoding changes +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.4 + - @backstage/plugin-search-common@1.2.3 + +## 1.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 1.3.0-next.1 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index eccd5a8304..f95a25ee40 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.3.0-next.1", + "version": "1.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 8fd1432c3a..cd25c33475 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-sentry +## 0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.5.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.5.3-next.1 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index e83531f95a..454b1b0259 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.5.3-next.1", + "version": "0.5.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index bbe2b74584..d151c6cdb4 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-shortcuts +## 0.3.10 + +### Patch Changes + +- 8a7174e297c: Marked `LocalStoredShortcuts` as deprecated, replacing it with `DefaultShortcutsApi` whose naming more clearly suggests that the shortcuts aren't necessarily stored locally (it depends on the storage implementation). +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/types@1.0.2 + +## 0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.10-next.1 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 4695c858c3..21dd39256d 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.10-next.1", + "version": "0.3.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index cf90264ece..ab84aef856 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-sonarqube-backend +## 0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 9b452471de..28b61aa1be 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.1.10-next.1", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 3a599bfd5f..d9624d2449 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-sonarqube +## 0.6.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-sonarqube-react@0.1.5 + +## 0.6.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.6.7-next.1 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 566a5cf757..1fbe857d9d 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.6.7-next.1", + "version": "0.6.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 1fe8e00511..9685a0c003 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-splunk-on-call +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + +## 0.4.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.4.7-next.1 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 97204eed93..4d0a79927b 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.7-next.1", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 03006fd490..a82a7abb05 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-stack-overflow-backend +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/config@1.0.7 + - @backstage/plugin-search-common@1.2.3 + ## 0.2.1-next.1 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index fd08b70f52..29285a5972 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.2.1-next.1", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 4e70b57ce3..d0a05501a9 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-stack-overflow +## 0.1.15 + +### Patch Changes + +- c1ff65f315a: StackOverflowSearchResultListItem can now accept an empty result prop so that it can be rendered in the suggested SearchResultListItem pattern. +- Updated dependencies + - @backstage/plugin-home@0.5.2 + - @backstage/theme@0.3.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-search-common@1.2.3 + +## 0.1.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.5.2-next.2 + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.15-next.1 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index d30311eb61..5b9cdb0213 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.15-next.1", + "version": "0.1.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/stackstorm/CHANGELOG.md b/plugins/stackstorm/CHANGELOG.md index bf8fedd4c3..c75324e862 100644 --- a/plugins/stackstorm/CHANGELOG.md +++ b/plugins/stackstorm/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-stackstorm +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.2-next.0 ### Patch Changes diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json index c9a9e7fc16..f1ba49ca0b 100644 --- a/plugins/stackstorm/package.json +++ b/plugins/stackstorm/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-stackstorm", "description": "A Backstage plugin that integrates towards StackStorm", - "version": "0.1.2-next.0", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 864c0cb830..fd3e6023f8 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-tech-insights-common@0.2.10 + ## 0.1.29-next.1 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 489f36e2f8..46ae292ff5 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.29-next.1", + "version": "0.1.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index 1c3b902c3f..faaa4b1960 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-tech-insights-backend +## 0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/plugin-tech-insights-node@0.4.3 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + ## 0.5.11-next.1 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 09bb9c8d6f..2525d1e914 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.11-next.1", + "version": "0.5.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index e5eec67a40..ee4a160a76 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-tech-insights-node +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + ## 0.4.3-next.1 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index bc5c0816f7..b97076a11e 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.4.3-next.1", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index a59782e2cc..4f36cfba16 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-tech-insights +## 0.3.10 + +### Patch Changes + +- 22963209d23: Added the possibility to customize the check description in the scorecard component. + + - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. + + Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. + As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## 0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.3.10-next.1 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index e8ead43ad6..a6facfff46 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.10-next.1", + "version": "0.3.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index c28aa05ea9..8250d4bfe8 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-tech-radar +## 0.6.4 + +### Patch Changes + +- be4fa53fab8: Fix description links when clicking entry in radar. +- Added the ability to display a timeline to each entry in the details box +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + +## 0.6.4-next.2 + +### Patch Changes + +- be4fa53fab8: Fix description links when clicking entry in radar. +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.6.4-next.1 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 4621f89c87..7fb7520e25 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.6.4-next.1", + "version": "0.6.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx index af9e840ead..66940cd1d7 100644 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx +++ b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx @@ -26,6 +26,7 @@ export type Props = { value: number; color: string; url?: string; + links?: Array<{ title: string; url: string }>; moved?: number; description?: string; timeline?: EntrySnapshot[]; @@ -73,6 +74,7 @@ const RadarEntry = (props: Props): JSX.Element => { title, color, url, + links, value, x, y, @@ -112,6 +114,7 @@ const RadarEntry = (props: Props): JSX.Element => { description={description ? description : 'no description'} timeline={timeline ? timeline : []} url={url} + links={links} /> )} {description ? ( diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx index 957017692b..0fb6e3a36a 100644 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx +++ b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx @@ -73,6 +73,7 @@ const RadarPlot = (props: Props): JSX.Element => { color={entry.color || ''} value={(entry?.index || 0) + 1} url={entry.url} + links={entry.links} description={entry.description} moved={entry.moved} title={entry.title} diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index cb41a62031..ede86cb6bb 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-techdocs@1.6.2 + - @backstage/plugin-catalog@1.11.0 + - @backstage/core-app-api@1.8.0 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/test-utils@1.3.1 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/core-plugin-api@1.5.1 + +## 1.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/test-utils@1.3.1-next.2 + - @backstage/plugin-catalog@1.11.0-next.2 + - @backstage/plugin-techdocs@1.6.2-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 1.0.13-next.1 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 27ae3ccadd..2e31a0d6bd 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.13-next.1", + "version": "1.0.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 8df2623fa0..309a3d3ea6 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-techdocs-backend +## 1.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.1 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-catalog-common@1.0.13 + - @backstage/plugin-permission-common@0.7.5 + - @backstage/plugin-search-common@1.2.3 + ## 1.6.2-next.1 ### Patch Changes diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/catalog-info.yaml b/plugins/techdocs-backend/examples/documented-component-uffizzi/catalog-info.yaml new file mode 100644 index 0000000000..a4d46593d3 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/catalog-info.yaml @@ -0,0 +1,12 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: documented-component-uffizzi + title: Documented Component (Uffizzi) + description: A Service with TechDocs documentation. Excl. PlantUML extension. + annotations: + backstage.io/techdocs-ref: dir:. +spec: + type: service + lifecycle: experimental + owner: user:guest diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/code/code-sample.md b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/code/code-sample.md new file mode 100644 index 0000000000..f41ab1d506 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/code/code-sample.md @@ -0,0 +1,31 @@ +# Sample Code + +This page provides some sample code which may be used in your example component. + +This code uses TypeScript, and the Markdown code fence to wrap the code. + +```typescript +const serviceEntityPage = ( + + + + + + + + + + + + +); +``` + +Here is an example of Python code: + +```python +def getUsersInGroup(targetGroup, secure=False): + + if __debug__: + print('targetGroup=[' + targetGroup + ']') +``` diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/extensions.md b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/extensions.md new file mode 100644 index 0000000000..2b101efdef --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/extensions.md @@ -0,0 +1,99 @@ +# Plugins & Extensions + +Just by including the TechDocs Core Plugin to your MkDocs site included with Backstage, +you gain the immediate use of a variety of popular plugins and extensions to MkDocs. + +For more information and full details of the available features, see the +[`mkdocs-techdocs-core` repository](https://github.com/backstage/mkdocs-techdocs-core#mkdocs-plugins-and-extensions). + +This page provides a demonstration of some of the available features. + +## Admonitions + +Admonitions are call outs that help catch a users attention. + +To define an admonition simply put the following Markdown into your content: + +``` +!!! warn + Defining admonitions can be addicting. +``` + +And they end up looking like this: + + +!!! warn + Defining admonitions can be addicting. + + +!!! note + You can learn a lot about TechDocs by just visiting the Backstage web site at + https://backstage.io/docs. + + +!!! info + TechDocs is the core feature that supports documentation as code in Backstage. + + +!!! tip + Don't forget to spell check your documentation. + +## Pymdownx Extensions + +Pymdownx (Python Markdown extensions) are a variety of smaller additions. + +### Details + + +??? note "What is the answer to life, the universe, and everything? (click me for the answer)" + The answer is 42. + + +??? note "What is 4 plus 4?" + The answer is 8. + + +???+ note "How do I get support?" + You can get support by opening an issue in this repository. This detail is open by default + so it's more easily visible without requiring the user to click to open it. + +### Task Lists + +Automatic rendering of Markdown task lists. + +- [x] Phase 1 +- [x] Phase 2 +- [ ] Phase 3 + +### Emojis + +Very nice job on documentation! :thumbsup: + +I've read a lot of documentation, but I love :heart: this document. + +Weather: :sunny: :umbrella: :cloud: :snowflake: + +Animals: :tiger: :horse: :turtle: :wolf: :frog: + +### Attributes + +[A Download Link](./images/backstage-logo-cncf.svg){: download } + +![A Scaled Image](./images/backstage-logo-cncf.svg){: style="width: 100px" } + +### MDX truly sane lists + +- `attributes` + +- `customer` + - `first_name` + - `test` + - `family_name` + - `email` +- `person` + - `first_name` + - `family_name` + - `birth_date` +- `subscription_id` + +- `request` diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/images/backstage-logo-cncf.svg b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/images/backstage-logo-cncf.svg new file mode 100644 index 0000000000..b5ff591d1b --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/images/backstage-logo-cncf.svg @@ -0,0 +1 @@ +05 Logo_Black \ No newline at end of file diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/index.md b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/index.md new file mode 100644 index 0000000000..6295a69406 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/index.md @@ -0,0 +1,55 @@ +# Welcome! + +This is a basic example of documentation. It is intended as a showcase of some of the +features that TechDocs provides out of the box. + +You can see also: + +- [A sub page](sub-page.md) +- [Inline code examples](code/code-sample.md) +- [Plugin & Extension examples](extensions.md) - Diagrams, emojis, visual formatting. + +## Basic Markdown + +Headings: + +# h1 + +## h2 + +### h3 + +#### h4 + +##### h5 + +###### h6 + +Here is a bulleted list: + +- Item one +- Item two +- Item Three + +Check out the [Markdown Guide](https://www.markdownguide.org/) to learn more about how to +simply create documentation. + +You can also learn more about how to configure and setup this documentation in Backstage, +[read up on the TechDocs Overview](https://backstage.io/docs/features/techdocs/). + +## Image Example + +This documentation is powered by Backstage's TechDocs feature: + +![Backstage Logo](images/backstage-logo-cncf.svg) + +## Table Example + +While this documentation isn't comprehensive, in the future it should cover the following +topics outlined in this example table: + +| Topic | Description | +| ------- | ------------------------------------------------------------ | +| Topic 1 | An introductory topic to help you learn about the component. | +| Topic 2 | A more detailed topic that explains more information. | +| Topic 3 | A final topic that provides conclusions and lessons learned. | diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/sub-page.md b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/sub-page.md new file mode 100644 index 0000000000..987f5e8a95 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/docs/sub-page.md @@ -0,0 +1,12 @@ +# Another page in our documentation + +This sub-page can be used to elaborate on a specific part of the component. + +## Details + +It is linked off the main page, and due to its inclusion in the `mkdocs.yml` file, +becomes part of the auto-generated site navigation. + +## MkDocs + +Visit https://www.mkdocs.org for more information about the MkDocs tool. diff --git a/plugins/techdocs-backend/examples/documented-component-uffizzi/mkdocs.yml b/plugins/techdocs-backend/examples/documented-component-uffizzi/mkdocs.yml new file mode 100644 index 0000000000..1a159a4d12 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component-uffizzi/mkdocs.yml @@ -0,0 +1,12 @@ +site_name: 'Example Documentation' +repo_url: https://github.com/backstage/backstage +edit_uri: edit/master/plugins/techdocs-backend/examples/documented-component/docs + +nav: + - Home: index.md + - Subpage: sub-page.md + - 'Code Sample': code/code-sample.md + - Extensions: extensions.md + +plugins: + - techdocs-core diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index b90c299621..999bc7f93b 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.6.2-next.1", + "version": "1.6.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 283f08934f..01765d39de 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.13 + +### Patch Changes + +- 6afc7f052ca: Show cursor pointer when hovering on lightbox +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/integration@1.4.5 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/core-plugin-api@1.5.1 + +## 1.0.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 1.0.13-next.1 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 763696fbbf..7ef4a1f2c1 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.13-next.1", + "version": "1.0.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs-module-addons-contrib/src/LigthBox/lightbox.css b/plugins/techdocs-module-addons-contrib/src/LigthBox/lightbox.css index 63170792f1..3371d0fa53 100644 --- a/plugins/techdocs-module-addons-contrib/src/LigthBox/lightbox.css +++ b/plugins/techdocs-module-addons-contrib/src/LigthBox/lightbox.css @@ -5,3 +5,7 @@ color: rgba(0, 0, 0, 0.87); text-shadow: none; } + +.pswp__img { + cursor: pointer !important; +} diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index e3715430c9..7737a13a13 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-techdocs-node +## 1.7.1 + +### Patch Changes + +- 3659c71c5d9: Standardize `@aws-sdk` v3 versions +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/integration-aws-node@0.1.3 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + ## 1.7.1-next.1 ### Patch Changes diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 2513033dc3..d3ec2232cd 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.7.1-next.1", + "version": "1.7.1", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -39,11 +39,11 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@aws-sdk/client-s3": "^3.208.0", - "@aws-sdk/credential-providers": "^3.208.0", - "@aws-sdk/lib-storage": "^3.208.0", - "@aws-sdk/node-http-handler": "^3.208.0", - "@aws-sdk/types": "^3.208.0", + "@aws-sdk/client-s3": "^3.310.0", + "@aws-sdk/credential-providers": "^3.310.0", + "@aws-sdk/lib-storage": "^3.310.0", + "@aws-sdk/node-http-handler": "^3.310.0", + "@aws-sdk/types": "^3.310.0", "@azure/identity": "^2.1.0", "@azure/storage-blob": "^12.5.0", "@backstage/backend-common": "workspace:^", diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index d201805fb5..9176553916 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-techdocs-react +## 1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/version-bridge@1.0.4 + +## 1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 1.1.6-next.0 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 318f8d56de..ee523969c1 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.1.6-next.0", + "version": "1.1.6", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 31a3653f2e..5d21c2a5fe 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-techdocs +## 1.6.2 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + ## 1.6.2-next.1 ### Patch Changes diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index 6e14c52939..27af44bb13 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -20,11 +20,14 @@ import { ReactNode } from 'react'; import { ResultHighlight } from '@backstage/plugin-search-common'; import { RouteRef } from '@backstage/core-plugin-api'; import { SearchResultListItemExtensionProps } from '@backstage/plugin-search-react'; +import { SyncResult as SyncResult_2 } from '@backstage/plugin-techdocs-react'; import { TableColumn } from '@backstage/core-components'; import { TableOptions } from '@backstage/core-components'; import { TableProps } from '@backstage/core-components'; +import { TechDocsApi as TechDocsApi_2 } from '@backstage/plugin-techdocs-react'; import { TechDocsEntityMetadata as TechDocsEntityMetadata_2 } from '@backstage/plugin-techdocs-react'; import { TechDocsMetadata as TechDocsMetadata_2 } from '@backstage/plugin-techdocs-react'; +import { TechDocsStorageApi as TechDocsStorageApi_2 } from '@backstage/plugin-techdocs-react'; import { ToolbarProps } from '@material-ui/core'; import { UserListFilterKind } from '@backstage/plugin-catalog-react'; @@ -237,7 +240,7 @@ export interface TechDocsApi { export const techdocsApiRef: ApiRef; // @public -export class TechDocsClient implements TechDocsApi { +export class TechDocsClient implements TechDocsApi_2 { constructor(options: { configApi: Config; discoveryApi: DiscoveryApi; @@ -442,7 +445,7 @@ export interface TechDocsStorageApi { export const techdocsStorageApiRef: ApiRef; // @public -export class TechDocsStorageClient implements TechDocsStorageApi { +export class TechDocsStorageClient implements TechDocsStorageApi_2 { constructor(options: { configApi: Config; discoveryApi: DiscoveryApi; @@ -471,6 +474,6 @@ export class TechDocsStorageClient implements TechDocsStorageApi { syncEntityDocs( entityId: CompoundEntityRef, logHandler?: (line: string) => void, - ): Promise; + ): Promise; } ``` diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index d0a6e49d13..cf6315286b 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.6.2-next.1", + "version": "1.6.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/techdocs/src/client.ts b/plugins/techdocs/src/client.ts index 499a56580c..8680e14468 100644 --- a/plugins/techdocs/src/client.ts +++ b/plugins/techdocs/src/client.ts @@ -23,11 +23,13 @@ import { } from '@backstage/core-plugin-api'; import { NotFoundError, ResponseError } from '@backstage/errors'; import { + SyncResult, + TechDocsApi, TechDocsEntityMetadata, TechDocsMetadata, + TechDocsStorageApi, } from '@backstage/plugin-techdocs-react'; import { EventSourcePolyfill } from 'event-source-polyfill'; -import { SyncResult, TechDocsApi, TechDocsStorageApi } from './api'; /** * API to talk to `techdocs-backend`. @@ -189,7 +191,7 @@ export class TechDocsStorageClient implements TechDocsStorageApi { * @param entityId - Object containing entity data like name, namespace, etc. * @param logHandler - Callback to receive log messages from the build process * @returns Whether documents are currently synchronized to newest version - * @throws Throws error on error from sync endpoint in Techdocs Backend + * @throws Throws error on error from sync endpoint in TechDocs Backend */ async syncEntityDocs( entityId: CompoundEntityRef, diff --git a/plugins/techdocs/src/home/components/TechDocsPageWrapper.tsx b/plugins/techdocs/src/home/components/TechDocsPageWrapper.tsx index 52511bda19..a6192c13ee 100644 --- a/plugins/techdocs/src/home/components/TechDocsPageWrapper.tsx +++ b/plugins/techdocs/src/home/components/TechDocsPageWrapper.tsx @@ -29,7 +29,7 @@ export type TechDocsPageWrapperProps = { }; /** - * Component wrapping a techdocs page with Page and Header components + * Component wrapping a TechDocs page with Page and Header components * * @public */ diff --git a/plugins/techdocs/src/reader/README.md b/plugins/techdocs/src/reader/README.md index fe1d1ff488..58697298c6 100644 --- a/plugins/techdocs/src/reader/README.md +++ b/plugins/techdocs/src/reader/README.md @@ -2,7 +2,7 @@ The TechDocs reader is a component that fetches a remote page, runs transformers on it and renders it into a shadow dom. -Currently there's no easy way to customize which transformers to run or add new ones. If that is needed you would have to fork the techdocs plugin and make your changes in that fork. +Currently there's no easy way to customize which transformers to run or add new ones. If that is needed you would have to fork the TechDocs plugin and make your changes in that fork. Transformers are functions that optionally takes in parameters from the Reader.tsx component and returns a function which gets passed the DOM of the fetched page. A very simple transformer can look like this. diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 84d8807698..17a2eb8cf8 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-todo-backend +## 0.1.42 + +### Patch Changes + +- 901f1ada325: Added OpenAPI schema +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/integration@1.4.5 + - @backstage/plugin-catalog-node@1.3.6 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-client@1.4.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.1.42-next.1 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index d98a44f874..84da46ced1 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.42-next.1", + "version": "0.1.42", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,6 +45,7 @@ "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-openapi-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", diff --git a/plugins/todo-backend/src/schema/openapi.generated.ts b/plugins/todo-backend/src/schema/openapi.generated.ts new file mode 100644 index 0000000000..54486a5615 --- /dev/null +++ b/plugins/todo-backend/src/schema/openapi.generated.ts @@ -0,0 +1,208 @@ +/* + * Copyright 2023 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. + */ + +// ****************************************************************** +// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * +// ****************************************************************** + +export default { + openapi: '3.0.3', + info: { + title: '@backstage/plugin-todo-backend', + version: '1', + description: + 'The Backstage backend plugin that provides source code todo comment browsing.', + license: { + name: 'Apache-2.0', + url: 'http://www.apache.org/licenses/LICENSE-2.0.html', + }, + contact: {}, + }, + servers: [ + { + url: '/', + }, + ], + components: { + examples: {}, + headers: {}, + parameters: {}, + requestBodies: {}, + responses: {}, + schemas: { + TodoItem: { + type: 'object', + properties: { + text: { + type: 'string', + description: 'The contents of the TODO comment', + }, + tag: { + type: 'string', + description: 'The tag used, e.g. TODO, FIXME', + }, + author: { + type: 'string', + description: 'References author, if any', + }, + viewUrl: { + type: 'string', + description: 'URL used to view the file', + }, + lineNumber: { + type: 'integer', + description: 'The line number of the file that the TODO occurs at', + }, + repoFilePath: { + type: 'string', + description: + 'The path of the file containing the TODO within the repo', + }, + }, + required: ['text', 'tag'], + additionalProperties: false, + }, + }, + securitySchemes: { + JWT: { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + }, + }, + }, + paths: { + '/v1/todos': { + get: { + operationId: 'ListTodos', + responses: { + '200': { + description: 'Ok', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + items: { + type: 'array', + items: { + $ref: '#/components/schemas/TodoItem', + }, + }, + totalCount: { + type: 'integer', + }, + offset: { + type: 'integer', + }, + limit: { + type: 'integer', + }, + }, + required: ['items', 'totalCount', 'offset', 'limit'], + additionalProperties: false, + }, + }, + }, + }, + '400': { + description: 'Bad request', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + error: { + type: 'object', + properties: { + message: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + security: [ + {}, + { + JWT: [], + }, + ], + parameters: [ + { + name: 'entity', + in: 'query', + required: true, + schema: { + type: 'string', + minLength: 1, + description: 'A reference to the entity to list TODO items for', + }, + }, + { + name: 'orderBy', + in: 'query', + required: false, + schema: { + type: 'string', + pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$', + description: + 'The field and direction used to sort the listed TODO items', + }, + }, + { + name: 'filter', + in: 'query', + required: false, + schema: { + type: 'array', + description: + 'A list of filters used to narrow down the listed TODO items', + items: { + type: 'string', + pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$', + }, + }, + }, + { + name: 'offset', + in: 'query', + required: false, + schema: { + type: 'integer', + minimum: 0, + description: 'The offset at which to start listing TODO items', + }, + }, + { + name: 'limit', + in: 'query', + required: false, + schema: { + type: 'integer', + minimum: 1, + description: 'The number of TODO items to list', + }, + }, + ], + }, + }, + }, +} as const; diff --git a/plugins/todo-backend/src/schema/openapi.yaml b/plugins/todo-backend/src/schema/openapi.yaml new file mode 100644 index 0000000000..3fba129644 --- /dev/null +++ b/plugins/todo-backend/src/schema/openapi.yaml @@ -0,0 +1,132 @@ +openapi: 3.0.3 + +info: + title: '@backstage/plugin-todo-backend' + version: '1' + description: The Backstage backend plugin that provides source code todo comment browsing. + license: + name: Apache-2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + contact: {} + +servers: + - url: / + +components: + examples: {} + headers: {} + parameters: {} + requestBodies: {} + responses: {} + schemas: + TodoItem: + type: object + properties: + text: + type: string + description: The contents of the TODO comment + tag: + type: string + description: The tag used, e.g. TODO, FIXME + author: + type: string + description: References author, if any + viewUrl: + type: string + description: URL used to view the file + lineNumber: + type: integer + description: The line number of the file that the TODO occurs at + repoFilePath: + type: string + description: The path of the file containing the TODO within the repo + required: + - text + - tag + additionalProperties: false + securitySchemes: + JWT: + type: http + scheme: bearer + bearerFormat: JWT +paths: + /v1/todos: + get: + operationId: ListTodos + responses: + '200': + description: Ok + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/TodoItem' + totalCount: + type: integer + offset: + type: integer + limit: + type: integer + required: + - items + - totalCount + - offset + - limit + additionalProperties: false + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: object + properties: + message: + type: string + security: + - {} + - JWT: [] + parameters: + - name: entity + in: query + required: true + schema: + type: string + minLength: 1 + description: A reference to the entity to list TODO items for + - name: orderBy + in: query + required: false + schema: + type: string + pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$' + description: The field and direction used to sort the listed TODO items + - name: filter + in: query + required: false + schema: + type: array + description: A list of filters used to narrow down the listed TODO items + items: + type: string + pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$' + - name: offset + in: query + required: false + schema: + type: integer + minimum: 0 + description: The offset at which to start listing TODO items + - name: limit + in: query + required: false + schema: + type: integer + minimum: 1 + description: The number of TODO items to list diff --git a/plugins/todo-backend/src/service/router.ts b/plugins/todo-backend/src/service/router.ts index 5954fab009..364cbef6b0 100644 --- a/plugins/todo-backend/src/service/router.ts +++ b/plugins/todo-backend/src/service/router.ts @@ -25,6 +25,8 @@ import { parseIntegerParam, parseOrderByParam, } from '../lib/utils'; +import spec from '../schema/openapi.generated'; +import type { ApiRouter } from '@backstage/backend-openapi-utils'; /** @public */ export interface RouterOptions { @@ -37,7 +39,7 @@ export async function createRouter( ): Promise { const { todoService } = options; - const router = Router(); + const router = Router() as ApiRouter; router.use(express.json()); router.get('/v1/todos', async (req, res) => { diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index cb9e1464ff..960f71c444 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-todo +## 0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.20-next.1 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index f8a86b9cb2..f388d19885 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.20-next.1", + "version": "0.2.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 4420e63f8e..bf3b2630e0 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-user-settings-backend +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-auth-node@0.2.14 + - @backstage/backend-plugin-api@0.5.2 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 6fdeee038d..25cc5ee812 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.1.9-next.1", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 92558dfba7..7240ceccd9 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-user-settings +## 0.7.3 + +### Patch Changes + +- 473db605a4f: Fix config schema definition. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-app-api@1.8.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-app-api@1.8.0-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.7.3-next.1 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index b55293d414..55672e358a 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.7.3-next.1", + "version": "0.7.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -78,7 +78,8 @@ "type": "object", "additionalProperties": { "type": "object", - "visibility": "frontend" + "visibility": "frontend", + "additionalProperties": true } } } diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 33fcd6017c..ceaa496252 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-vault-backend +## 0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/backend-tasks@0.5.2 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + ## 0.3.1-next.1 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index 0f4467ca80..26e30c91ad 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.3.1-next.1", + "version": "0.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index 7af7f47adc..7c2f0f0adf 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-vault +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/catalog-model@1.3.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/core-plugin-api@1.5.1 + ## 0.1.12-next.1 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 6d97b0a5e9..0cc1df1d6b 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.12-next.1", + "version": "0.1.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index eccce54f0b..641a0697e0 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-xcmetrics +## 0.2.38 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/core-components@0.13.1 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + +## 0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/core-plugin-api@1.5.1 + ## 0.2.38-next.0 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 18b86eb0ee..5f21dd0951 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.38-next.0", + "version": "0.2.38", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/yarn.lock b/yarn.lock index 7778cb8e7c..ae964f254d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -531,13 +531,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/abort-controller@npm:3.310.0, @aws-sdk/abort-controller@npm:^3.208.0": - version: 3.310.0 - resolution: "@aws-sdk/abort-controller@npm:3.310.0" +"@aws-sdk/abort-controller@npm:3.329.0, @aws-sdk/abort-controller@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/abort-controller@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: ca081fbec7419ff7bc03b7fddcfe7be1d5e390290c819069f42672f5a66415b55d90a81de899c384fd3368396390e3573c66345a8f91683e600c6caff64a239f + checksum: 37f65402b2599d19793a2fc9de18d61eed4663fd8b565f2782bc5ab5b9bcf0adc4600275dca3860d66dbcf1f347e5c506ca2cb41842e9f64d625cad9b4676fef languageName: node linkType: hard @@ -550,532 +550,620 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.312.0": - version: 3.312.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.312.0" +"@aws-sdk/client-cognito-identity@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.329.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.312.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/credential-provider-node": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-signing": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 1bbd307c899e112bc265927e052afebe7e25d111fce8e765c85c40a84152910549dd25d9d8f4cb0561773f9be72c5a71f0ff9577582f61ee30e27d4188dc06d5 + checksum: bb60cbad68375fda44f7a4cd538feb55ed744a8cf510c56f8fe71c7611fef75b6b7d4bf6ff2190283b5bedf184f4cb13d6867ccebbf8588e6176de09133c9e52 languageName: node linkType: hard -"@aws-sdk/client-s3@npm:^3.208.0": - version: 3.312.0 - resolution: "@aws-sdk/client-s3@npm:3.312.0" +"@aws-sdk/client-eks@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/client-eks@npm:3.329.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 + "@aws-sdk/util-base64": 3.310.0 + "@aws-sdk/util-body-length-browser": 3.310.0 + "@aws-sdk/util-body-length-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 + "@aws-sdk/util-utf8": 3.310.0 + "@aws-sdk/util-waiter": 3.329.0 + tslib: ^2.5.0 + uuid: ^8.3.2 + checksum: 373176c8cc23b3aef3f1b1088568b2ec1d635597119fe8d2633850a7edb214c14e8990665045c70658076b27413aa8915f04946ab13c0e15eb1041a1954e2f1e + languageName: node + linkType: hard + +"@aws-sdk/client-organizations@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/client-organizations@npm:3.329.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 + "@aws-sdk/util-base64": 3.310.0 + "@aws-sdk/util-body-length-browser": 3.310.0 + "@aws-sdk/util-body-length-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 + "@aws-sdk/util-utf8": 3.310.0 + tslib: ^2.5.0 + checksum: d36b5d05005a3603153c11f1b0fd4272fe5c5fb3af7209c9788d15731016e635c1ae45bfdcbd0efe69c4b3e197dc6ee31e1df708ecfafa13f04742eaf444a670 + languageName: node + linkType: hard + +"@aws-sdk/client-s3@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/client-s3@npm:3.329.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.312.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/credential-provider-node": 3.310.0 - "@aws-sdk/eventstream-serde-browser": 3.310.0 - "@aws-sdk/eventstream-serde-config-resolver": 3.310.0 - "@aws-sdk/eventstream-serde-node": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-blob-browser": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/hash-stream-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/md5-js": 3.310.0 - "@aws-sdk/middleware-bucket-endpoint": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-expect-continue": 3.310.0 - "@aws-sdk/middleware-flexible-checksums": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-location-constraint": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-sdk-s3": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-signing": 3.310.0 - "@aws-sdk/middleware-ssec": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/signature-v4-multi-region": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/eventstream-serde-browser": 3.329.0 + "@aws-sdk/eventstream-serde-config-resolver": 3.329.0 + "@aws-sdk/eventstream-serde-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-blob-browser": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/hash-stream-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/md5-js": 3.329.0 + "@aws-sdk/middleware-bucket-endpoint": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-expect-continue": 3.329.0 + "@aws-sdk/middleware-flexible-checksums": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-location-constraint": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-sdk-s3": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-ssec": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/signature-v4-multi-region": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-stream-browser": 3.310.0 - "@aws-sdk/util-stream-node": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-stream-browser": 3.329.0 + "@aws-sdk/util-stream-node": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 - "@aws-sdk/util-waiter": 3.310.0 + "@aws-sdk/util-waiter": 3.329.0 "@aws-sdk/xml-builder": 3.310.0 fast-xml-parser: 4.1.2 tslib: ^2.5.0 - checksum: 20764e30d10a0280961ba45491f6b26f7ca27e430da348fa4ce257b75fe1b67d5dbf0f4e3109c9db33c8c3269ba1f62d4a2d53a45977e1271dbc189bfcc1d4ef + checksum: dd413da8c16a0ed2246e60a65c18dad143535e72f234da35ba85561dc14ec06e669f155bf37039c9dc7a15547bc6ce792d9fec89d7b0a896b37aa54ebb2ae16c languageName: node linkType: hard -"@aws-sdk/client-sqs@npm:^3.208.0": - version: 3.312.0 - resolution: "@aws-sdk/client-sqs@npm:3.312.0" +"@aws-sdk/client-sqs@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/client-sqs@npm:3.329.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.312.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/credential-provider-node": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/md5-js": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-sdk-sqs": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-signing": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/md5-js": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-sdk-sqs": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 fast-xml-parser: 4.1.2 tslib: ^2.5.0 - checksum: 0cc2c0cb6b835d5dd29ff0f146fd4f7d4d7501ebdd419144a704a6092a029e774f580a6dcb6e668779fe86c589b6df884ef09f1866d3d28abbeb1787fe7eb58e + checksum: 10559224f1d77ed6ddef93fd1b91518e5b24b0c75a71287cc5b3e9000424af1b253a17ad1bc852c48849cecd735b99aed916f04370d0f3755ba3b65bd45a478c languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.310.0" +"@aws-sdk/client-sso-oidc@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.329.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 7e4a013983978a02e390b621d76716c1649eb7b8889ad239f082b737ef204182879c4ab735a702ebd9c9a5a406c1fefd16c53d7f327db2cbaea88ebbf9bc6123 + checksum: 6ddb767778548b4e6952a0efc867fa53c37b37149d3b762577db80c1d3b51a5c9a92e85fb34affd91c73e64b55a9e9184bf63b1301f3bd5034daa7effd645dc6 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/client-sso@npm:3.310.0" +"@aws-sdk/client-sso@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/client-sso@npm:3.329.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 5d7461e2102634c336e3748f91f51e9e53c8dc2fa50441535fad8f6926f368131224935b958b05a071d9c61357adfc8db885ac2adb5be9cee94243cecc3454d3 + checksum: 27227bdefc73d6c5501418c752d4015217ac787c063bccf805aba2c213fb7abcc10862cb2faab5cfa7a36e29eeacb59aea61717cbb8aaf075cd69962bab3abc9 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.312.0, @aws-sdk/client-sts@npm:^3.208.0": - version: 3.312.0 - resolution: "@aws-sdk/client-sts@npm:3.312.0" +"@aws-sdk/client-sts@npm:3.329.0, @aws-sdk/client-sts@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/client-sts@npm:3.329.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/credential-provider-node": 3.310.0 - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/hash-node": 3.310.0 - "@aws-sdk/invalid-dependency": 3.310.0 - "@aws-sdk/middleware-content-length": 3.310.0 - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/middleware-host-header": 3.310.0 - "@aws-sdk/middleware-logger": 3.310.0 - "@aws-sdk/middleware-recursion-detection": 3.310.0 - "@aws-sdk/middleware-retry": 3.310.0 - "@aws-sdk/middleware-sdk-sts": 3.310.0 - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/middleware-signing": 3.310.0 - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/middleware-user-agent": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/hash-node": 3.329.0 + "@aws-sdk/invalid-dependency": 3.329.0 + "@aws-sdk/middleware-content-length": 3.329.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/middleware-host-header": 3.329.0 + "@aws-sdk/middleware-logger": 3.329.0 + "@aws-sdk/middleware-recursion-detection": 3.329.0 + "@aws-sdk/middleware-retry": 3.329.0 + "@aws-sdk/middleware-sdk-sts": 3.329.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/middleware-user-agent": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-body-length-browser": 3.310.0 "@aws-sdk/util-body-length-node": 3.310.0 - "@aws-sdk/util-defaults-mode-browser": 3.310.0 - "@aws-sdk/util-defaults-mode-node": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 - "@aws-sdk/util-user-agent-browser": 3.310.0 - "@aws-sdk/util-user-agent-node": 3.310.0 + "@aws-sdk/util-defaults-mode-browser": 3.329.0 + "@aws-sdk/util-defaults-mode-node": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 + "@aws-sdk/util-user-agent-browser": 3.329.0 + "@aws-sdk/util-user-agent-node": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 fast-xml-parser: 4.1.2 tslib: ^2.5.0 - checksum: ad0b444605cbb53caf7ef2c637a79923adeca133d8fc74ee45208828bc8546ae69a2738ce77f6aae376c53d41e2f59ec7703d4a3c364066cacef06427a746e8c + checksum: f9dc6bf6cf640bff23f5aed792921cbf7048df88c840092b4727f8e32c4a14abf420e939a319167ee6bbcf7a1f5f61774d980a6c03e88afe516f7b662361a46a languageName: node linkType: hard -"@aws-sdk/config-resolver@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/config-resolver@npm:3.310.0" +"@aws-sdk/config-resolver@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/config-resolver@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-config-provider": 3.310.0 - "@aws-sdk/util-middleware": 3.310.0 + "@aws-sdk/util-middleware": 3.329.0 tslib: ^2.5.0 - checksum: ec80bc867304344d04b6d6bbf369234e7d296540ffb988c3f29bf96ea5e3ac959f86a699c8eecef3fea87491fd413aaed3137e4f7a89544cceedf09cce1c9a15 + checksum: c5838c0a60e955cda5fcd91361b168fe1bbedd997c9c4482383c98f2690149114f902d18a26ef3188b62734f2f3754cafed6283d4349d83eeb0d072b081f4ead languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.312.0": - version: 3.312.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.312.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.329.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.312.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/client-cognito-identity": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 4acd9f7bbd8cb9adabbd9b6465fe81f7bd47d5808b3a5fd3352e4e573a8ff718e56684e67631649f72d01078dc858278de1b5c227b8557d948d4c43abde99561 + checksum: d0d82fbe2cd88862dad13628de417c16c983b8fadd319b3a459d16298a25f90d34d7f054b68a688a292d590b73384d937fac6a1fbb18b77d262c5c5edaf95f94 languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.310.0" +"@aws-sdk/credential-provider-env@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 646e634e6f8429c1984475100a60066dd5d0c085b3e170dc0c05c55c824edb3b04d4c40496ab4318e9586b9ca1db0b20090d26919b0273351c82372a12cd9958 + checksum: 12cf04f542c722296adc4e6fbfe63334a60e7b1763b5e1ebfbaafcdcb332555d1f8cf9c855c249b056fb560a008957df4b7fd1551c04a7dbbebc6e3baad89eaa languageName: node linkType: hard -"@aws-sdk/credential-provider-imds@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-imds@npm:3.310.0" +"@aws-sdk/credential-provider-imds@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-imds@npm:3.329.0" dependencies: - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 tslib: ^2.5.0 - checksum: 24915e2f108e37bef21b9bec07f7ab38f25bf3ed55c55ad318ae8e030e042123980855b977c13714580232d2c0a514e71efd61848e68c221716c2110c160ab13 + checksum: 853b42758e271f85b290aef5d5a2d717b3231016f1541a657408572c4a8fe7f2a209450bc1133715007b895d3c74d065b90a229e31351493bacf368720676471 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.310.0" +"@aws-sdk/credential-provider-ini@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.329.0" dependencies: - "@aws-sdk/credential-provider-env": 3.310.0 - "@aws-sdk/credential-provider-imds": 3.310.0 - "@aws-sdk/credential-provider-process": 3.310.0 - "@aws-sdk/credential-provider-sso": 3.310.0 - "@aws-sdk/credential-provider-web-identity": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/credential-provider-env": 3.329.0 + "@aws-sdk/credential-provider-imds": 3.329.0 + "@aws-sdk/credential-provider-process": 3.329.0 + "@aws-sdk/credential-provider-sso": 3.329.0 + "@aws-sdk/credential-provider-web-identity": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 9d0adc90a942680ccc1aa135b1d5b42a32a1db1aee0a1d1cfeac2f20347b28a5b8a33bb982eec9e2ff1204ffacfff3cc4b1065cdd11f035edcde4142ff3e3125 + checksum: 2fe427272d08e1baad780d9b7ce53badf2fa4f58f54f65f6b21ba6e54b32bc908dc18a1e934ba39148f7293f78e6b8009e0c22e503e6f3c2d25b0f2c54534ba7 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.310.0, @aws-sdk/credential-provider-node@npm:^3.208.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.310.0" +"@aws-sdk/credential-provider-node@npm:3.329.0, @aws-sdk/credential-provider-node@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.329.0" dependencies: - "@aws-sdk/credential-provider-env": 3.310.0 - "@aws-sdk/credential-provider-imds": 3.310.0 - "@aws-sdk/credential-provider-ini": 3.310.0 - "@aws-sdk/credential-provider-process": 3.310.0 - "@aws-sdk/credential-provider-sso": 3.310.0 - "@aws-sdk/credential-provider-web-identity": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/credential-provider-env": 3.329.0 + "@aws-sdk/credential-provider-imds": 3.329.0 + "@aws-sdk/credential-provider-ini": 3.329.0 + "@aws-sdk/credential-provider-process": 3.329.0 + "@aws-sdk/credential-provider-sso": 3.329.0 + "@aws-sdk/credential-provider-web-identity": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 893aacd840a69363e11cbfb50c915aa3f515f40d6f5a93018f2fd1d7775af40d2a2fd083422aabc817f433e0f89fe5cdaaea7059b0ec59e8f38c78c97b35995a + checksum: 472bc96b16c589db5e2f938f9f5cc29236ca62186d988b2b06b1bd9378ed681a3e290c9ba4b4adbaabf803e0a1182060df0b5c071ba30a47c8e302f4f55b22a1 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.310.0" +"@aws-sdk/credential-provider-process@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 12c4ab1f34d5a045d56ca22bc6c834292da15d518129133babcbede056adb46f4e898489e1b54e7e5ee3472d1116882217f5a29af0a46cc40d2f3aa00ef6767f + checksum: 198fb80efab5a29ea0d72e96f0f45adbe3532b56deca045c7cc4089bf7a5388f73e340df135525f4392d942e3a1c516d3cd692d4de7f4d4e6ef9241d7470ee7a languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.310.0" +"@aws-sdk/credential-provider-sso@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.329.0" dependencies: - "@aws-sdk/client-sso": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/token-providers": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/client-sso": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/token-providers": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 595c3f393430e1c9ddb0b276b605e87a8a6d461fe5d7bfa7e9b033fd06f3d5bcb1f4fe6b74e7eb5fa38d1d88181f8be5398bb3c1a53ae18caada9a59eed1ba21 + checksum: 0c925dc2c5a76606e0338240a1348bce52bee94c6d3f2d7dec179168439857abe0b4c9ff5ab29d59af5af4c7e2228f2ac1dad0f86803f68f1574dbcd9afa96f3 languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.310.0" +"@aws-sdk/credential-provider-web-identity@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 62dd9362bb48e010cb84dfcb92461478b2d1fa830e47e078a9bd074999eb231b0ef4e273e585fce5ed0135768b90bafcbe9ca5df83fc6c0bc5d227ec74271a82 + checksum: fcbc21976d471999285904cb4924b49d85d846ecc3495a2fc6a5e8ff611765da1fdfd98f5cc828af29e43a0e087c3f49dae0186ef8e43de4afd07bec43c6fc69 languageName: node linkType: hard -"@aws-sdk/credential-providers@npm:^3.208.0": - version: 3.312.0 - resolution: "@aws-sdk/credential-providers@npm:3.312.0" +"@aws-sdk/credential-providers@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/credential-providers@npm:3.329.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.312.0 - "@aws-sdk/client-sso": 3.310.0 - "@aws-sdk/client-sts": 3.312.0 - "@aws-sdk/credential-provider-cognito-identity": 3.312.0 - "@aws-sdk/credential-provider-env": 3.310.0 - "@aws-sdk/credential-provider-imds": 3.310.0 - "@aws-sdk/credential-provider-ini": 3.310.0 - "@aws-sdk/credential-provider-node": 3.310.0 - "@aws-sdk/credential-provider-process": 3.310.0 - "@aws-sdk/credential-provider-sso": 3.310.0 - "@aws-sdk/credential-provider-web-identity": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/client-cognito-identity": 3.329.0 + "@aws-sdk/client-sso": 3.329.0 + "@aws-sdk/client-sts": 3.329.0 + "@aws-sdk/credential-provider-cognito-identity": 3.329.0 + "@aws-sdk/credential-provider-env": 3.329.0 + "@aws-sdk/credential-provider-imds": 3.329.0 + "@aws-sdk/credential-provider-ini": 3.329.0 + "@aws-sdk/credential-provider-node": 3.329.0 + "@aws-sdk/credential-provider-process": 3.329.0 + "@aws-sdk/credential-provider-sso": 3.329.0 + "@aws-sdk/credential-provider-web-identity": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: d47501b81e3f37c50110a12f58491407c95bebfa341ed80040aeefab236a3496dc33100da244e1e4467d2e2d62be19faec04f2e52a236a5c5ec2e1feeb12ceee + checksum: 534ac502c710d23750648166b9a1d51099cc64f23e9fbda586ddbb2cfb6a393b99cd18a0ad5f5f6c431ca106f4e752b2e6bd71ba309b1fb3ca45145c04a90ef7 languageName: node linkType: hard -"@aws-sdk/eventstream-codec@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/eventstream-codec@npm:3.310.0" +"@aws-sdk/eventstream-codec@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/eventstream-codec@npm:3.329.0" dependencies: "@aws-crypto/crc32": 3.0.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-hex-encoding": 3.310.0 tslib: ^2.5.0 - checksum: 2866186a5303bb8b9151ea69f22bace420317c4ec3b5c9aa0beb9bd007aca419a519be2d911b8119ddfd1c0a8358cc9e0f957ca3a460b3009846e0e5517a8f7a + checksum: c57070e439b8a9009cb11f47b51f233b2fc6cff785a6e8ab869e8d7b299dd358fd14053f943ef14fbf1d4affd7e23de8f976ece09d4b180ca0a053e74724d35b languageName: node linkType: hard -"@aws-sdk/eventstream-serde-browser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/eventstream-serde-browser@npm:3.310.0" +"@aws-sdk/eventstream-serde-browser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/eventstream-serde-browser@npm:3.329.0" dependencies: - "@aws-sdk/eventstream-serde-universal": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/eventstream-serde-universal": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 10a8dc5999c3f8f683ef399c8866d274232e235bf526c481da2527c24e23836e362c647c92103dcabdf52107b8fd0c46ae8e9f8d2f79741f198022cd94b150f1 + checksum: 07d318f9bf41427947dfe885f1fe4b1f2a08934fd43db4c44fd941baf92bb989e8b9e380597e0b7834e3190e697dd72ab2ba5c8fff3437ab84efae3706a5e217 languageName: node linkType: hard -"@aws-sdk/eventstream-serde-config-resolver@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/eventstream-serde-config-resolver@npm:3.310.0" +"@aws-sdk/eventstream-serde-config-resolver@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/eventstream-serde-config-resolver@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 9ad39115d8bd163fe441fa8128e102c1e6157890c7731d7ab797b63a636f378f30a2695adcf41b58f52b6bfd71b68c2bafe51d1cf4f984b124746341d13ced6b + checksum: 51a4c94beffcf74f956f1750a99788fdfd15d1dcddbc5ab2b5c8d0a089a430cad16b2b27515aac84c4dc0ff304a8d69212a2af411e921eb3fd59f49ed3ef7b48 languageName: node linkType: hard -"@aws-sdk/eventstream-serde-node@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/eventstream-serde-node@npm:3.310.0" +"@aws-sdk/eventstream-serde-node@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/eventstream-serde-node@npm:3.329.0" dependencies: - "@aws-sdk/eventstream-serde-universal": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/eventstream-serde-universal": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 1a695e39e5bbd4088d5790c8b4389dd635b7f6300892868d35e8711ef7ea5c1f2f50886c9ac55de5eae9619c49fe864c6e530e575a06231300294211a36827b3 + checksum: 398fd78b194eef3a95f84d056d5d1690e0342a3f643aae2ac40465cefa81ff21dcd299d93d53ffbdf22c49807a932c6798d17a913f466f3f7ed4c9b23ea136fa languageName: node linkType: hard -"@aws-sdk/eventstream-serde-universal@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/eventstream-serde-universal@npm:3.310.0" +"@aws-sdk/eventstream-serde-universal@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/eventstream-serde-universal@npm:3.329.0" dependencies: - "@aws-sdk/eventstream-codec": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/eventstream-codec": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 10ce20184cdfd826600f610418e07add4e70073470cf23a5b3b8b4ea479ab096eb70c6eeb9e87bcd30e040270b3c0519fe187aad3363c85bc357a048014a8de4 + checksum: ffdaa375d9a97079380514849b4f561ba24955da754f5bfebc9406dc43fe93674c0275278d27b2568313056a04be3de6f1783f7a471b501e84736e1f2c95155a languageName: node linkType: hard -"@aws-sdk/fetch-http-handler@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/fetch-http-handler@npm:3.310.0" +"@aws-sdk/fetch-http-handler@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/fetch-http-handler@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/querystring-builder": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/querystring-builder": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-base64": 3.310.0 tslib: ^2.5.0 - checksum: 5daa78ee3e2a0a6bd07c3b8bc658ebd88a063b17025ec23454c2eb433859972d60a550fdc62969754488c3f4d624fbf3e758af8ea891c994998deca0f8e3903e + checksum: 85795cd97f1538ed4d713b370377667f18bf3ead1326815452b8636e6ae07af3726f75bb95f2ad31d6fa06eb802903344f3413724ca4e593fbe8a05c533c8e52 languageName: node linkType: hard -"@aws-sdk/hash-blob-browser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/hash-blob-browser@npm:3.310.0" +"@aws-sdk/hash-blob-browser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/hash-blob-browser@npm:3.329.0" dependencies: "@aws-sdk/chunked-blob-reader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 58908f51a89f61b5c0ed036beeda58d7e54d1385ca56447c057569671b110be0dad2bec4618daa35a8170c8b3e0e193bd473f695d0be269ec2dd06915bcaa9b9 + checksum: 9b8e0a5ae442f0cce372bf79a0e634c6b99eb4fa39cea91bda437de51e4da4fbe288e0229c04f778d865b9281e2e93fbfe0b269a492ecd7285e9f84f3816cb24 languageName: node linkType: hard -"@aws-sdk/hash-node@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/hash-node@npm:3.310.0" +"@aws-sdk/hash-node@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/hash-node@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-buffer-from": 3.310.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 379c04c78679d68730272b89fa397cdfcd444ae2f21d7dc51953e9885842469de40593efbb86b2399342e022b2ba17926841ef0a9fb108809296b2df416226c1 + checksum: 19f505bc9ef34b15277acb13cfed9f06efc6a4d648df45aed5eb12c0c3566a6338e00bf126081fb5429149c69ba99b9120aebe5940eb91ac7a6686a5f0c9cabf languageName: node linkType: hard -"@aws-sdk/hash-stream-node@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/hash-stream-node@npm:3.310.0" +"@aws-sdk/hash-stream-node@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/hash-stream-node@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 42fe6f8eddd67565019d935b109e9f3acf0eacfd940712859e718db8f1ca4550c305f0fc4dad9944624ea10e0ff7e15f895d13cce0cdcf5c614d3bff39263ecf + checksum: 3901b6fa62e9e09a21c16c13f929a401338366c12a0ba695b830a5195859740cc6853cb22cc01c164fbfb9db817dabac2f260033cbb027f506abaae7a499f2c5 languageName: node linkType: hard -"@aws-sdk/invalid-dependency@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/invalid-dependency@npm:3.310.0" +"@aws-sdk/invalid-dependency@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/invalid-dependency@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: e38d09615e273617583e845b2cd3683c9d27d54234a98bec7da1cf959107329f73e62b322479415155016ed62c7d849cd6542d6e9e33572f6ed542013c15821c + checksum: 0e5f122ab2529386f7531bdf1494968264b6e2addd89e484bb3f28ad3bd8d438d381923e61cfd4ea3dfe930982d484541d9b8c562a19de90fec06791d6bcc586 languageName: node linkType: hard @@ -1088,12 +1176,12 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/lib-storage@npm:^3.208.0": - version: 3.312.0 - resolution: "@aws-sdk/lib-storage@npm:3.312.0" +"@aws-sdk/lib-storage@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/lib-storage@npm:3.329.0" dependencies: - "@aws-sdk/middleware-endpoint": 3.310.0 - "@aws-sdk/smithy-client": 3.310.0 + "@aws-sdk/middleware-endpoint": 3.329.0 + "@aws-sdk/smithy-client": 3.329.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 @@ -1101,391 +1189,391 @@ __metadata: peerDependencies: "@aws-sdk/abort-controller": ^3.0.0 "@aws-sdk/client-s3": ^3.0.0 - checksum: ce09963885a749e6347ffe8d2ea94e2572629f31041f7859f71d98436ff863822862c13c2c465af5a11aacc3193d0c599f19d455b8251ebcbe95fc44eba1cd0e + checksum: 47e3ec6cc4882e6b016c3a161ca0bbfd733f3b6a89a3ee2af80df17ca14113104df79f32d901ce460899da8d01182fc7fddc1ddef3858c5e2020ffa29231ed20 languageName: node linkType: hard -"@aws-sdk/md5-js@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/md5-js@npm:3.310.0" +"@aws-sdk/md5-js@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/md5-js@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 1939591f5f384e55ce9d610cbf3e8ae25e76c14489385ef73ee0c674b641351820d17e2406943e2b3ee4a3736d280256f2b79bb381e18e78440faf74d4ca04cf + checksum: 3471b9c5e62a4c37c609a6575ea521028cd2852bbaf1a55e8d077ed0c4d90c4339e6c6a3015553e9549d1e519ade4d68acc98571a1fa9e880d66c907cfd12977 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.310.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-arn-parser": 3.310.0 "@aws-sdk/util-config-provider": 3.310.0 tslib: ^2.5.0 - checksum: cf300c0226a649bdd7128c5c44ff03bac58119390c8bf82a712094e95c2df4c0b1693a74256968294d8ad397828fb2f7d5f0d9355c08d1d67a24888255d6dfd2 + checksum: bda4e039ee9655d528e6416005bb4efa13e9dcd16a7c16d1693ed7970702bce3c2ff8ea6204a3c090c9881cf7a6ccf2385f44ac9fcc9b8d8addf6a27fa93d56b languageName: node linkType: hard -"@aws-sdk/middleware-content-length@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-content-length@npm:3.310.0" +"@aws-sdk/middleware-content-length@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-content-length@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 66977eac6aa9ce0d7c5640e357608b79eec18919d4e94c37aacf76801ac1b24471a3483755d1ab30a416aa2aa10c9da02fb6241f11e29ea99079ff04bdf012b1 + checksum: ffc2f7d2c7b2c7398d54b118c7392816f8e24ac4b350794f0c501a9ca82c67d4b6f90d9442f6ffa71b3e1f75da20b5274390b0a18d8f4adcedf5893251023588 languageName: node linkType: hard -"@aws-sdk/middleware-endpoint@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-endpoint@npm:3.310.0" +"@aws-sdk/middleware-endpoint@npm:3.329.0, @aws-sdk/middleware-endpoint@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-endpoint@npm:3.329.0" dependencies: - "@aws-sdk/middleware-serde": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/url-parser": 3.310.0 - "@aws-sdk/util-middleware": 3.310.0 + "@aws-sdk/middleware-serde": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/url-parser": 3.329.0 + "@aws-sdk/util-middleware": 3.329.0 tslib: ^2.5.0 - checksum: 7d61ceaff3fb6be779f9b0597fceccbc1d5ebbc83b83d93ac184fc6451e60b4acca9eebb0c83c9e1c6b34400bd39345b498227860892ed51eda2b99f16ff0566 + checksum: ed662d778a4ab7b05ee4fba607d6b72e798ee969752fabe2141546a184a71f2daf206a2b8300fa68de0339ebc2646fb8fdf9bf22ebf9cf68495518465c1f1bcc languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.310.0" +"@aws-sdk/middleware-expect-continue@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 717eb502c00bc5b32cbb210657b0cfdec837f5296f86043bce40f43535f345e689639b017c71271709bdee0a58cc4ade6324ae0bcccfcdc0789e8699b2ce9f76 + checksum: 462dd314e80ce17e5975e4b4ce162d41a44691845dfff6b6ae7bd0eb449402bd2d1f93ab577513faf089c9fb193b9a79ccd1ccfb1eb917576e42c2618e4d2ef9 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.310.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.329.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 "@aws-sdk/is-array-buffer": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: be99290968c5e00053dd2e43683d77cd08dbe1acff64189e522d9e4aa1440c8e6ae86d784ef4d163a059f725b52fdd5812b54594d70a9773c25feef24e63c9c3 + checksum: 06a3ca6c7dfd679c092d2f504caf8c72107243efa408f9e04055e4ce74dd32806b5f786f84dd6e9586c4ba92c81f7f3817e7191df45546c775b8f9b682e266f5 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.310.0" +"@aws-sdk/middleware-host-header@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 9b1bf8598f9bf44a0cd992f08820ce54fb7ce5f33366796b7328a003c2efc00754a3e0bfd56be87b221ca0f15b4c00f5caf736bf196cb9a4b3ca26dfd3e7f7db + checksum: a83d44c24fedf605cfc1b715f5529fc5c424c11ef77a29fa483e390d379a0ca0a4839249d64e71a8a3f096a2ed97ddf95fc8726149bbb9343f50d6522f0ed46b languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.310.0" +"@aws-sdk/middleware-location-constraint@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 2ca1a7d9ca47c29468c4286731f0a1dc15e0233f0a59bc1dad3f3ed5917b1e5d7b344c705660cc3afdecb153f2e2f203e9ae37eb018d6a56aaeba7ad05ebd466 + checksum: 04565ae85637cec8c2d0fc574479e36cc953c86e9ec22e4ebc22d52b832b2d4e50b71750f72d4ddcabf1ce820ce8edccf9efb5fadcf292e9ad842289d16999c9 languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-logger@npm:3.310.0" +"@aws-sdk/middleware-logger@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-logger@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 13014451afaadf11524754f959aaa4c4e7763442dedef841d693159370720e40d20a6113851b87b6cab6c709d92b1e952adede0ec9948dbaa1546dbff1e477d0 + checksum: 85031d5d562ae34a550c9ce355cce2e322924dfbb6140e255444056a6f97ab3a98db9d9854572c0d1cf2d73e0e086320a6324cabedac66e975007f1140148c49 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.310.0" +"@aws-sdk/middleware-recursion-detection@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: a5db6bec59a5232ebc28296d165d09fb94d74e9232d32f49f77bccbbae62cda58215d2f8a17979f1714b9dd07c25a989caae8bc7eee1f57c57d67328788fa401 + checksum: 921683327a3047d9fa8c1c027bee44330ae769a45bdd205a7a5d1a262fde09c404c574a60497e87987f01670daf56b2e0084fdacded87270917f04e99ac437a4 languageName: node linkType: hard -"@aws-sdk/middleware-retry@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-retry@npm:3.310.0" +"@aws-sdk/middleware-retry@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-retry@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/service-error-classification": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/util-middleware": 3.310.0 - "@aws-sdk/util-retry": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/service-error-classification": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/util-middleware": 3.329.0 + "@aws-sdk/util-retry": 3.329.0 tslib: ^2.5.0 uuid: ^8.3.2 - checksum: 7d69c187d4cfad62df01b445596f812157e4028b377f34c40f6b272df3660a48ebbc6a0c86eba98b1b19454ade6be7b1459c62ffe8a1924725a23e330d2814b7 + checksum: 1c3eed0037a06c5201a8c102c1d5b946571a8085bde0ccc9fafb3c62343414383ee94883c07e7b2e4e870852a7a54798e1cbaeda17062d7a4b7178f6355f3119 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.310.0" +"@aws-sdk/middleware-sdk-s3@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-arn-parser": 3.310.0 tslib: ^2.5.0 - checksum: b546560c2fc3fcbb37d38b5d02e3f8349592d66a6a2ef4571b72d0bb6c398d0c2bb7008665d58541efc577372f2e1aae88ea1318ba0fe8613583397604dff02e + checksum: 4de1fc7b4ac6b01c3e65ee8e25151b73d3f78d5ac3949d799b10252a42a8b55bb00242822757bbc790dde545745fb8d2f83feb09442eec83846c431d98aeab27 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.310.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-hex-encoding": 3.310.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: b8207b1625e52d02b3a3f28153e84f3a9c44bc9812ceb0ca1da798aa9fe576b9aef26c2da10dd6c8742c64e734eec93fd5123d769079b99a19bd105599fe11e5 + checksum: 77faadbf799b37ac036cba465174cabbc5557aa59944c20d05b8253e54266aed7846bf6135f7b7f0ab183da555ba255782e257a3d4364a3ffe0efe6ea738f97a languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sts@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-sdk-sts@npm:3.310.0" +"@aws-sdk/middleware-sdk-sts@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-sdk-sts@npm:3.329.0" dependencies: - "@aws-sdk/middleware-signing": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/middleware-signing": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 80debd2f2371f65f7c37f2f0101e9e8ac520ef74d6a8ba54fedfbad6d63653732f7ce6095bae7bf3adbfec61bfa4d9f816b8eb5550cdadec825b400cf74bb2ce + checksum: 0c5450726c546f6f4b3de50e1a9a1757ca267f6fece5ef3dcf1560955eea885d0476debbce0d3f67290db77e7b894a386f5822b7d5bde8d9bcfea5af94735918 languageName: node linkType: hard -"@aws-sdk/middleware-serde@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-serde@npm:3.310.0" +"@aws-sdk/middleware-serde@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-serde@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 95c2c1b15906a93c9869be36563757f08cd53a0f385882759943e59a1fd31be777260fb075feaa1a9bb919cf1696739e7b2da89049cec0bee1a649a838f9184c + checksum: 29b72c582f6c783396e6e7a5a9bd6416ceebb18a15b55187267cdb3e2a6f18e2395d2aafdbeedeedce8c014b0d7fbd40d151accc1e409fe8741cee346b0c9ce1 languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-signing@npm:3.310.0" +"@aws-sdk/middleware-signing@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-signing@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/signature-v4": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/util-middleware": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/signature-v4": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/util-middleware": 3.329.0 tslib: ^2.5.0 - checksum: f1db11435250075fc563de375c8c513dbaba7b9939ae99c70074d90622f9aea0cc339cd10f0eff63251eba462b73f564389bfb9dcfe6868f36892488dea0494b + checksum: 6dad12d4e3cfad3dd508ad2177da3ec5d54015d606c670999659c21dfaaf41b1cbb52c92704a9ecf0f82e322ae9f62a0639c2e3cf1b201c08d78b99638abdd1c languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.310.0" +"@aws-sdk/middleware-ssec@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: a6d9cde8d826c4baae7908e82035e892f8b4706e648efa1ff5a8706285efabd17f9fe8d48b5b0fb42b17f227fba257b7d95b99baf9e152246cb95a2fe23a547f + checksum: 819623a8a3a8d3518fcc194025a470a06d0b6889cb88f165a7f49aea6b1e4396effe448ac94b8a27928aca8752502960d6899a5597f293f0542ee9d0e5a872da languageName: node linkType: hard -"@aws-sdk/middleware-stack@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-stack@npm:3.310.0" +"@aws-sdk/middleware-stack@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-stack@npm:3.329.0" dependencies: tslib: ^2.5.0 - checksum: ad90bb8cf2a8e3211869ed0c08e240e0df7097ff42a9bbfa6dd96ad79a8b741c096199082f1be40a2ae2b1fbeb56a4bc510cdaf431dd90a5db73e32fe7184ee2 + checksum: 34b2ac02f8bd21a6803064de8059a866aa776c8a7962d40e11d072801291b9f5e78daac5adf91931ca1d19b11e2e972467c6b9679bf7c049b5f63ce50eb214d9 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.310.0" +"@aws-sdk/middleware-user-agent@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/types": 3.310.0 - "@aws-sdk/util-endpoints": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/types": 3.329.0 + "@aws-sdk/util-endpoints": 3.329.0 tslib: ^2.5.0 - checksum: 571ebfce481a2d814270248e728c68030661cb3f0de97908b73e1d446c508d5af06cb088c68c67b23ce9671873c1872ab681b9383d48797b5a1c53a7030085ff + checksum: 6241246ea640bbe23148fa632e6735f6f25c3e1d32d01bcc21e733b2c11aba4c899acfe9982d98eab4d0dcddc451d60c8d6710ed1240e61ad428df24d10cc64e languageName: node linkType: hard -"@aws-sdk/node-config-provider@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/node-config-provider@npm:3.310.0" +"@aws-sdk/node-config-provider@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/node-config-provider@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 95d017aa1bb94e323c288bc0ce5edba5c4605eeabe779249beb5faee958c26f6eebb7f1664328b83d1024e441eb4e4f9fce9c1bb764637f83f7ebf20b8359a77 + checksum: 25178c8857f48931079b204e2c904f7960edbae2a34bb6ccb8f27991d807a61e05dcf42cad4bb56cb98c5c12aedebea58a840b3bea30a06c174cb6758b03e2d5 languageName: node linkType: hard -"@aws-sdk/node-http-handler@npm:3.310.0, @aws-sdk/node-http-handler@npm:^3.208.0": - version: 3.310.0 - resolution: "@aws-sdk/node-http-handler@npm:3.310.0" +"@aws-sdk/node-http-handler@npm:3.329.0, @aws-sdk/node-http-handler@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/node-http-handler@npm:3.329.0" dependencies: - "@aws-sdk/abort-controller": 3.310.0 - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/querystring-builder": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/abort-controller": 3.329.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/querystring-builder": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 781cc864972bf52f884b580e43b9b659ab34a6ca7d7772d8e76107a51fe0930124c01024bc7ac1c4e99324319c594b809373ebc4752ea0a2e3a984ccf57aa535 + checksum: 0560640be504cbe1f4d5098cdef917085472f476487d2fcd5225ab67063dca53718a30d48cb255790d327356f8b544bba491175dd2d6c9b8319327f5204909ae languageName: node linkType: hard -"@aws-sdk/property-provider@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/property-provider@npm:3.310.0" +"@aws-sdk/property-provider@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/property-provider@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 8a906b3f4e482f4d5be0ef1277fcb22fb005e834c916919373187f8cf6b17b0d464f37a12770d152a553b7a505ed9981504a0c30f73f273d251ed93ff29616e1 + checksum: 17c8cb7d28b55ff9ba1f81da87dff42815919c6458eec422d1a45d7d809f7ee531e7b5daeb2bb63eab569eb12c0d6bce270a66e060c8c19d841d1894211f6dfd languageName: node linkType: hard -"@aws-sdk/protocol-http@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/protocol-http@npm:3.310.0" +"@aws-sdk/protocol-http@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/protocol-http@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 4bfe2b7a93d52ded21472d6347483fb52dfd2414d4ff07d8e3a2869d7676e866a9bfa29e9e7ac4fa3849c7109740a39e3d1e646a02d8bb4b7c7b402f53b18450 + checksum: 6b88be86283c67fd6fc9c3f8260c02e916f6f9b4c2a554a261809d6e48ef3dbae0a6c02ecde90cbfcd77f8066dbb37c2263e22fbeb20c2a5ac19e3ffc2582b67 languageName: node linkType: hard -"@aws-sdk/querystring-builder@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/querystring-builder@npm:3.310.0" +"@aws-sdk/querystring-builder@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/querystring-builder@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-uri-escape": 3.310.0 tslib: ^2.5.0 - checksum: c06ba9ec67d6e6a5f4c1099461b9b2d6cb12a278e6ec2fe198f68ba115ce1e05425f29cf6859f8a005ae7123036b6dadc325d18b35165c7049233f9d04670dcb + checksum: 188a3e6ee142af8ec8fa6563db831e70069a4f94487f25b02da608fe569d881c4b696abff8bbf98ff154107ed4b57170f1b6633ec55a7ddbffabb3cd745c243f languageName: node linkType: hard -"@aws-sdk/querystring-parser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/querystring-parser@npm:3.310.0" +"@aws-sdk/querystring-parser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/querystring-parser@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 5e9d8700918db3daa89440f7c0aa9d0ee37e30bab13892f12602267259160ff73eaccd7e01521bf71f4a0f59da9cb632f75e583d927900f2acddc4913e3422f8 + checksum: eebb633db0bf9d9a3854ab2f83526468b430f57fb8b5cd2c737683facf717d96876acb4a837e17235458e728ebf375a26321ea6dd4dc07f5eb9eaa6e4efad1b5 languageName: node linkType: hard -"@aws-sdk/service-error-classification@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/service-error-classification@npm:3.310.0" - checksum: a600a7634fe932b52676ea33851230173ce66b45f4c8350c91616e37f9cbd43e8f6e7e3fc9761fd14ca7ecd2c7ca90ca806fc555e383d0bf0ee2bdb6a4d73888 +"@aws-sdk/service-error-classification@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/service-error-classification@npm:3.329.0" + checksum: 77b19ffd3fa926b3e4b5f5aee64ff3159af6fa7c9f3a643fe7505690a2bd7d67e2ff8790ea3be21458c95c0eeb65687e4dd01140c352d170549368c0ff908936 languageName: node linkType: hard -"@aws-sdk/shared-ini-file-loader@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/shared-ini-file-loader@npm:3.310.0" +"@aws-sdk/shared-ini-file-loader@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/shared-ini-file-loader@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: aa3ffb5cb4320ee936102be200dbacb95be0bd85088c692de268d56c175dd4329757a83847d1c4e689b98f3810f729596a1a0b726f1ea0a8d00c78516fc10cc3 + checksum: ee5e57d38a17eb4ebb073daa3e1f91bf07c3a5746410470a628765e0b49176ac880a86b6e09279137fdda7a44a38666cb311fd3ed523d9a3c4d4766d1ebeeb7e languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.310.0" +"@aws-sdk/signature-v4-multi-region@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.329.0" dependencies: - "@aws-sdk/protocol-http": 3.310.0 - "@aws-sdk/signature-v4": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/protocol-http": 3.329.0 + "@aws-sdk/signature-v4": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 peerDependencies: "@aws-sdk/signature-v4-crt": ^3.118.0 peerDependenciesMeta: "@aws-sdk/signature-v4-crt": optional: true - checksum: ef88c3ba8dba0fda1204ec9358e46ea2bbefb0a258b21e2c83142b3ea9bb9be3eba428b38297da28bb4a5e93f9c27de8711aa6f219b3cbced4eba0c443c9b68a + checksum: c9ae1a68919674b6444cdb64e865e08b72f6a6127c7f43bffbbfb7457d48efc9ea5c89e58e5e451d1ec28c0d735969e4985fee25a7bca5b9949264d8de2763fc languageName: node linkType: hard -"@aws-sdk/signature-v4@npm:3.310.0, @aws-sdk/signature-v4@npm:^3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/signature-v4@npm:3.310.0" +"@aws-sdk/signature-v4@npm:3.329.0, @aws-sdk/signature-v4@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/signature-v4@npm:3.329.0" dependencies: "@aws-sdk/is-array-buffer": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-hex-encoding": 3.310.0 - "@aws-sdk/util-middleware": 3.310.0 + "@aws-sdk/util-middleware": 3.329.0 "@aws-sdk/util-uri-escape": 3.310.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 0adaf05a005a8a468301f24482d25de3a35554debc98ab8eeb0444c529c02a63dc7e7754d990e9464e1a17c1eb1f6ffdcc178bcd7d35c87587e4cc41574c69b3 + checksum: 8bf81f260f8a6a75e43f172bc049b777d081ca75e8456b21331895c0dba2486b804a8e7aed12ebb178e421aacc515fc873141682d7100c045da60b9425b9c432 languageName: node linkType: hard -"@aws-sdk/smithy-client@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/smithy-client@npm:3.310.0" +"@aws-sdk/smithy-client@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/smithy-client@npm:3.329.0" dependencies: - "@aws-sdk/middleware-stack": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/middleware-stack": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: a97b88e6ae3066abf136fe3d59ead258d459c4f37f69e6170a902d85194cb2d798519771b945880072776bbf0e77bfc18e15768dcbafc402f0f255d80bca0ba6 + checksum: 4235822be0165c44f780a704da01581c8f8476c6a11e2b421d6fa003a30e9ab3bb37c02289b5678194f6d89304b1a576a1fc79b646ac0c58b482f70ea24a4b16 languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/token-providers@npm:3.310.0" +"@aws-sdk/token-providers@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/token-providers@npm:3.329.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/shared-ini-file-loader": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/client-sso-oidc": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/shared-ini-file-loader": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: a38d5c562f0cc29ddcd6b52b8b4c872447824962055cdb77587fdc9e13e24e6a9acda1d7ea60e7b7e2dbfe8b27dc0ff03347e739b298099b7c1ebe67044ff8e1 + checksum: 87d1e4a13ce0cc4af50d4e1d5006967da69d5d1f384edaeea0057ca0a8f3397706934fea152d5f83d7be3c68c9a12c04edb2dbb0558b42cf200066f7d56643a8 languageName: node linkType: hard -"@aws-sdk/types@npm:3.310.0, @aws-sdk/types@npm:^3.208.0, @aws-sdk/types@npm:^3.222.0": - version: 3.310.0 - resolution: "@aws-sdk/types@npm:3.310.0" +"@aws-sdk/types@npm:3.329.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/types@npm:3.329.0" dependencies: tslib: ^2.5.0 - checksum: b11a91899614e14d40081ceab39cd3702254a5658c7b5e8862ef0d66dbffaa41c9a0f0d31e415d22f31c791b507699ba3a5fc7d87a540273386eb779be3807e4 + checksum: 2bbcd8e6ba2f813dc220c60e7ac0fa0d0990d49f88030fd8235479586716016c8f9d7aeaf1f4c1a64694275f33690bd1dd4ed46e127983201061e063da73f426 languageName: node linkType: hard -"@aws-sdk/url-parser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/url-parser@npm:3.310.0" +"@aws-sdk/url-parser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/url-parser@npm:3.329.0" dependencies: - "@aws-sdk/querystring-parser": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/querystring-parser": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: a9f5bec1cfa38cf2d244df1f6d7aad0f8e880a285d148678652ba14a3fb03fc0847defdc80a7e3ffb197d91e33d8cfb43325ee39f53c43c40ceb7fbd34f38fda + checksum: d5640fb2c21ebca56904641204bd51bb14b9d7cc1ae76860ce2e7d51cf5c1e76b09eefb98678d67651de2773a7137509017f22a93c8f2e7451666e10100072ec languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.310.0, @aws-sdk/util-arn-parser@npm:^3.208.0": +"@aws-sdk/util-arn-parser@npm:3.310.0, @aws-sdk/util-arn-parser@npm:^3.310.0": version: 3.310.0 resolution: "@aws-sdk/util-arn-parser@npm:3.310.0" dependencies: @@ -1541,39 +1629,39 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-browser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.310.0" +"@aws-sdk/util-defaults-mode-browser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.329.0" dependencies: - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 1f1847c41c43e167dec2e6f1a128ac9a486cc2e536b65d8d0e247131105cd2a46329297adc865ec164019850cbd425648add521dbde03417cacceaaf249555c2 + checksum: 217995ed68d7af117a0efa163ec22b0ee1700d4d1a3f4a1a950298e239788743886453dfb91f07c2b6c341497d489cae142872e629f6701c65d689132527be0d languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-node@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-defaults-mode-node@npm:3.310.0" +"@aws-sdk/util-defaults-mode-node@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-defaults-mode-node@npm:3.329.0" dependencies: - "@aws-sdk/config-resolver": 3.310.0 - "@aws-sdk/credential-provider-imds": 3.310.0 - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/property-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/config-resolver": 3.329.0 + "@aws-sdk/credential-provider-imds": 3.329.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/property-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: dca18909df6f8c72ae606c25920e2f686016de969aef2be4568cd6ce1fa0c45b3f946702d607b3279d267aaedff8b67251d4ee7bb4f76a38fca4299c81a7757d + checksum: 8b727977205638940da63fe3a4a88862d7a9491c3409543e67a7a9ee071f4c2459d24ca2e078a412710a5fa2146f6644356fbda69b9f3a9046c7d65f14902b8d languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-endpoints@npm:3.310.0" +"@aws-sdk/util-endpoints@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-endpoints@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 3f1c76b4c7662eeaf9dcf782739aa90812ed6920dd602a4a3779c80fbf3215efb15bd1ad82a30d022b577acd6049d35fbf79b45f6ae842e895be94db360d1b03 + checksum: 6d7c8bcd6a8a14d8597a77799d25fb36a79c0d4453f11257f1964e3230b26d46145a7c98d037f9b238100205733f6e15beb48887a85a52715aa120dbcf02cc69 languageName: node linkType: hard @@ -1595,48 +1683,48 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-middleware@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-middleware@npm:3.310.0" +"@aws-sdk/util-middleware@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-middleware@npm:3.329.0" dependencies: tslib: ^2.5.0 - checksum: 3c25a83361ce95dd3f66170d67fb39911a3f5bc21627ffaccef1880ad8c3602b6351f5c51e9c0bfef5b4037e5c66b9eadb291a9441db644811cf5640c35c587b + checksum: 23bc1ab195d31871edb2a7c9b3772911e881a39d70dfacedcf6e0308cbe95ec0ccb09f5f41f52458bff621d8e44dd3a4c94336da213d6d8074ffa0c0e334fad2 languageName: node linkType: hard -"@aws-sdk/util-retry@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-retry@npm:3.310.0" +"@aws-sdk/util-retry@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-retry@npm:3.329.0" dependencies: - "@aws-sdk/service-error-classification": 3.310.0 + "@aws-sdk/service-error-classification": 3.329.0 tslib: ^2.5.0 - checksum: a91b53ca40dd7ac423b46a4916a84567de163e84e63919e77d9a0694337323812b662580f6133442eb1c17885d0a2b5663cba9cadce4dabf5517dc34089b3399 + checksum: 56b5c3567f4b32d37faf93f69c7ca519a5300838065b896fdc291dbdd85e17551e00d44f536fb859e648ff2db2f1fb7176bc46aa2c44e5a947a3dd99b61f642e languageName: node linkType: hard -"@aws-sdk/util-stream-browser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-stream-browser@npm:3.310.0" +"@aws-sdk/util-stream-browser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-stream-browser@npm:3.329.0" dependencies: - "@aws-sdk/fetch-http-handler": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/fetch-http-handler": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-base64": 3.310.0 "@aws-sdk/util-hex-encoding": 3.310.0 "@aws-sdk/util-utf8": 3.310.0 tslib: ^2.5.0 - checksum: 0058cdb410bd5d9365ce28c436dff17a534dfea38cc411f2bc83b34aa1be24850feae19f73b2fc7c2865df5d38d1f2502eb8ab4d061b3a90f4823bc09031f30c + checksum: a3451714c437c7a33aefa52e37182d58d7ff8e632f1243ec40bba6a352a7e9a7c58fc8cb2f4ba68b969aadbae08290e7506b8c0762080e3502427d8c747f7644 languageName: node linkType: hard -"@aws-sdk/util-stream-node@npm:3.310.0, @aws-sdk/util-stream-node@npm:^3.208.0": - version: 3.310.0 - resolution: "@aws-sdk/util-stream-node@npm:3.310.0" +"@aws-sdk/util-stream-node@npm:3.329.0, @aws-sdk/util-stream-node@npm:^3.310.0": + version: 3.329.0 + resolution: "@aws-sdk/util-stream-node@npm:3.329.0" dependencies: - "@aws-sdk/node-http-handler": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/node-http-handler": 3.329.0 + "@aws-sdk/types": 3.329.0 "@aws-sdk/util-buffer-from": 3.310.0 tslib: ^2.5.0 - checksum: 05caf55f81dd8151adccc23bc2f3f0007e095fb554bec279ec0c8045a7d8da22ecaed238f5d12705ae77e77b7cd81119bb5da2f1a9788962f5361647cafdf9ca + checksum: 67e018f8a9ad7da48ceaed48419580e017d91743de3872c9a23900e104651029261d70faed4b7cf479d2c0902297d3c7385ea3393af7798d2e6a88e037a259fc languageName: node linkType: hard @@ -1649,30 +1737,30 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.310.0" +"@aws-sdk/util-user-agent-browser@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.329.0" dependencies: - "@aws-sdk/types": 3.310.0 + "@aws-sdk/types": 3.329.0 bowser: ^2.11.0 tslib: ^2.5.0 - checksum: 32fc6249e762fcba3f3111ed627b644855e8127bc354911fdcdbd0332ea1915872bb0984f19c049fbc4feaf17e3bb02ff11b13d3792103ee8902d00c7fe3ff84 + checksum: ced136d39db2eaa62621819025df1c881e909e37826322ad5d5cb78d51d8e866f88ac1fe90857543a8f7f1fa1111d50bd369fa49495e465a167769935410df45 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.310.0" +"@aws-sdk/util-user-agent-node@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.329.0" dependencies: - "@aws-sdk/node-config-provider": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/node-config-provider": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 82d214f814405a538df8afb259f6a3f2d373cd87adbc2895ac93e9d1f4ed9f4f8f6dcc0ae8ba55887e99e45b5ea83c7b1e5ed3efccbcdbbcaee6a863a638d183 + checksum: 33fae730d0cdb0743af867373f58201c5aea8e48a0f449c9df19c08269cc18fc4b523e481895e4ba5b2a43446ec417f12691249e8b0339c30849473f5f36085f languageName: node linkType: hard @@ -1695,14 +1783,14 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-waiter@npm:3.310.0": - version: 3.310.0 - resolution: "@aws-sdk/util-waiter@npm:3.310.0" +"@aws-sdk/util-waiter@npm:3.329.0": + version: 3.329.0 + resolution: "@aws-sdk/util-waiter@npm:3.329.0" dependencies: - "@aws-sdk/abort-controller": 3.310.0 - "@aws-sdk/types": 3.310.0 + "@aws-sdk/abort-controller": 3.329.0 + "@aws-sdk/types": 3.329.0 tslib: ^2.5.0 - checksum: 51eb9fbb9a21cd02c312f4639e520b934e2d6ea93eb7c0c1c71f3cf415d61b0a681e7f88209f9e49f3e84bba83480d1c14b0c0b069b610bd12753ff1c1d68f42 + checksum: 41f8796c3649313dee3cbc5a643c9bc1d23a54e35a990c41875a3397f18c57844a68e2f0efb585548f88f6047b7e2c31db8c833481839788cee3024bc92aad81 languageName: node linkType: hard @@ -3384,7 +3472,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.21.0 resolution: "@babel/runtime@npm:7.21.0" dependencies: @@ -3508,11 +3596,11 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/backend-common@workspace:packages/backend-common" dependencies: - "@aws-sdk/abort-controller": ^3.208.0 - "@aws-sdk/client-s3": ^3.208.0 - "@aws-sdk/credential-providers": ^3.208.0 - "@aws-sdk/types": ^3.208.0 - "@aws-sdk/util-stream-node": ^3.208.0 + "@aws-sdk/abort-controller": ^3.310.0 + "@aws-sdk/client-s3": ^3.310.0 + "@aws-sdk/credential-providers": ^3.310.0 + "@aws-sdk/types": ^3.310.0 + "@aws-sdk/util-stream-node": ^3.310.0 "@backstage/backend-app-api": "workspace:^" "@backstage/backend-dev-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" @@ -3699,7 +3787,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@^1.4.1, @backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": +"@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" dependencies: @@ -4000,110 +4088,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.12.3": - version: 0.12.5 - resolution: "@backstage/core-components@npm:0.12.5" - dependencies: - "@backstage/config": ^1.0.7 - "@backstage/core-plugin-api": ^1.5.0 - "@backstage/errors": ^1.1.5 - "@backstage/theme": ^0.2.18 - "@backstage/version-bridge": ^1.0.3 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.57 - "@react-hookz/web": ^20.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - history: ^5.0.0 - immer: ^9.0.1 - lodash: ^4.17.21 - pluralize: ^8.0.0 - prop-types: ^15.7.2 - qs: ^6.9.4 - rc-progress: 3.4.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.6 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ~3.18.0 - peerDependencies: - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 8308c1b90247911f6cf22963b530cef169287f508ff29d159d0c83758134dd43bd5acd2113350690a46a02246bc05dca975bcc38325000aefb1c93c80e2f19c7 - languageName: node - linkType: hard - -"@backstage/core-components@npm:^0.13.0": - version: 0.13.0 - resolution: "@backstage/core-components@npm:0.13.0" - dependencies: - "@backstage/config": ^1.0.7 - "@backstage/core-plugin-api": ^1.5.1 - "@backstage/errors": ^1.1.5 - "@backstage/theme": ^0.2.19 - "@backstage/version-bridge": ^1.0.4 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^20.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - history: ^5.0.0 - immer: ^9.0.1 - linkify-react: 4.1.1 - linkifyjs: 4.1.1 - lodash: ^4.17.21 - pluralize: ^8.0.0 - prop-types: ^15.7.2 - qs: ^6.9.4 - rc-progress: 3.4.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.21.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 49c5301ff45c6f7516e78e80f46b25d2efb8d9ba510c7718f94c25b1f7d9b2869840db7ec896fbf9d083ceca8fa8cddf718a78eeb074993e95d474195f4bc9cd - languageName: node - linkType: hard - -"@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@^0.13.0, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -4178,6 +4163,56 @@ __metadata: languageName: unknown linkType: soft +"@backstage/core-components@npm:^0.12.3": + version: 0.12.5 + resolution: "@backstage/core-components@npm:0.12.5" + dependencies: + "@backstage/config": ^1.0.7 + "@backstage/core-plugin-api": ^1.5.0 + "@backstage/errors": ^1.1.5 + "@backstage/theme": ^0.2.18 + "@backstage/version-bridge": ^1.0.3 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + "@react-hookz/web": ^20.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + history: ^5.0.0 + immer: ^9.0.1 + lodash: ^4.17.21 + pluralize: ^8.0.0 + prop-types: ^15.7.2 + qs: ^6.9.4 + rc-progress: 3.4.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.6 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ~3.18.0 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-dom: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 8308c1b90247911f6cf22963b530cef169287f508ff29d159d0c83758134dd43bd5acd2113350690a46a02246bc05dca975bcc38325000aefb1c93c80e2f19c7 + languageName: node + linkType: hard + "@backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@^1.5.0, @backstage/core-plugin-api@^1.5.1, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" @@ -4292,11 +4327,11 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/integration-aws-node@workspace:packages/integration-aws-node" dependencies: - "@aws-sdk/client-sts": ^3.208.0 - "@aws-sdk/credential-provider-node": ^3.208.0 - "@aws-sdk/credential-providers": ^3.208.0 - "@aws-sdk/types": ^3.208.0 - "@aws-sdk/util-arn-parser": ^3.208.0 + "@aws-sdk/client-sts": ^3.310.0 + "@aws-sdk/credential-provider-node": ^3.310.0 + "@aws-sdk/credential-providers": ^3.310.0 + "@aws-sdk/types": ^3.310.0 + "@aws-sdk/util-arn-parser": ^3.310.0 "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" @@ -4307,28 +4342,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.12": - version: 1.1.12 - resolution: "@backstage/integration-react@npm:1.1.12" - dependencies: - "@backstage/config": ^1.0.7 - "@backstage/core-components": ^0.13.0 - "@backstage/core-plugin-api": ^1.5.1 - "@backstage/integration": ^1.4.4 - "@backstage/theme": ^0.2.19 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: c7ae5754f074f3cee020a5dfca50deecaccd0f5a8510a1446bb1070d7b9b6e32a82564cff77b98ef63b19fde5a29aceaf4b8e8662dd1a3ed00c408c8ae06dc65 - languageName: node - linkType: hard - -"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@^1.1.12, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -4359,22 +4373,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration@npm:^1.4.4": - version: 1.4.4 - resolution: "@backstage/integration@npm:1.4.4" - dependencies: - "@backstage/config": ^1.0.7 - "@backstage/errors": ^1.1.5 - "@octokit/auth-app": ^4.0.0 - "@octokit/rest": ^19.0.3 - cross-fetch: ^3.1.5 - git-url-parse: ^13.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - checksum: 715310efe55b3c2fb93f5197bc1422917822a15a7550aae9d84b257bb0a6cff2bfab9a44296a977a56651499fbecd0ef31f954f92a62cc94bfbc7319d9a48c04 - languageName: node - linkType: hard - "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -4796,6 +4794,7 @@ __metadata: "@types/passport-strategy": ^0.2.35 "@types/xml2js": ^0.4.7 compression: ^1.7.4 + connect-session-knex: ^3.0.1 cookie-parser: ^1.4.5 cors: ^2.8.5 express: ^4.17.1 @@ -4991,11 +4990,8 @@ __metadata: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" - "@backstage/test-utils": "workspace:^" "@types/express": ^4.17.6 "@types/node": "*" badge-maker: ^3.3.0 @@ -5147,8 +5143,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-aws@workspace:plugins/catalog-backend-module-aws" dependencies: - "@aws-sdk/client-s3": ^3.208.0 - "@aws-sdk/util-stream-node": ^3.208.0 + "@aws-sdk/client-eks": ^3.310.0 + "@aws-sdk/client-organizations": ^3.310.0 + "@aws-sdk/client-s3": ^3.310.0 + "@aws-sdk/credential-providers": ^3.310.0 + "@aws-sdk/middleware-endpoint": ^3.310.0 + "@aws-sdk/types": ^3.310.0 + "@aws-sdk/util-stream-node": ^3.310.0 "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" @@ -5158,14 +5159,14 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" + "@backstage/integration-aws-node": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/types": "workspace:^" "@types/lodash": ^4.14.151 - aws-sdk: ^2.840.0 aws-sdk-client-mock: ^2.0.0 - aws-sdk-mock: ^5.2.1 + aws-sdk-client-mock-jest: ^2.0.0 lodash: ^4.17.21 luxon: ^3.0.0 p-limit: ^3.0.2 @@ -5535,7 +5536,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@^1.0.13, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.10, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5673,43 +5674,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.5.0": - version: 1.5.0 - resolution: "@backstage/plugin-catalog-react@npm:1.5.0" - dependencies: - "@backstage/catalog-client": ^1.4.1 - "@backstage/catalog-model": ^1.3.0 - "@backstage/core-components": ^0.13.0 - "@backstage/core-plugin-api": ^1.5.1 - "@backstage/errors": ^1.1.5 - "@backstage/integration": ^1.4.4 - "@backstage/plugin-catalog-common": ^1.0.13 - "@backstage/plugin-permission-common": ^0.7.5 - "@backstage/plugin-permission-react": ^0.4.12 - "@backstage/theme": ^0.2.19 - "@backstage/types": ^1.0.2 - "@backstage/version-bridge": ^1.0.4 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@types/react": ^16.13.1 || ^17.0.0 - classnames: ^2.2.6 - jwt-decode: ^3.1.0 - lodash: ^4.17.21 - material-ui-popup-state: ^1.9.3 - qs: ^6.9.4 - react-use: ^17.2.4 - yaml: ^2.0.0 - zen-observable: ^0.10.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 0ffa1a9ecf142df389e2ecdbda1fae1718d4b65782654d99cd1de562520aae6ecc4677c15aff50a10fee9d9e89a35d2978e53da8f5f7129deef02c7044eb6e46 - languageName: node - linkType: hard - -"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@^1.2.4, @backstage/plugin-catalog-react@^1.5.0, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -6146,6 +6111,86 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-devtools-backend@workspace:^, @backstage/plugin-devtools-backend@workspace:plugins/devtools-backend": + version: 0.0.0-use.local + resolution: "@backstage/plugin-devtools-backend@workspace:plugins/devtools-backend" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/cli-common": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/config-loader": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-devtools-common": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + "@backstage/plugin-permission-node": "workspace:^" + "@backstage/types": "workspace:^" + "@manypkg/get-packages": ^1.1.3 + "@types/express": "*" + "@types/minimist": ^1.2.0 + "@types/ping": ^0.4.1 + "@types/supertest": ^2.0.8 + "@types/yarnpkg__lockfile": ^1.1.4 + "@yarnpkg/lockfile": ^1.1.0 + "@yarnpkg/parsers": ^3.0.0-rc.4 + express: ^4.18.1 + express-promise-router: ^4.1.0 + fs-extra: ^10.0.0 + lodash: ^4.17.21 + msw: ^0.47.0 + node-fetch: ^2.6.7 + ping: ^0.4.1 + semver: ^7.3.2 + supertest: ^6.2.4 + winston: ^3.2.1 + yn: ^4.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-devtools-common@workspace:^, @backstage/plugin-devtools-common@workspace:plugins/devtools-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-devtools-common@workspace:plugins/devtools-common" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + "@backstage/types": "workspace:^" + languageName: unknown + linkType: soft + +"@backstage/plugin-devtools@workspace:^, @backstage/plugin-devtools@workspace:plugins/devtools": + version: 0.0.0-use.local + resolution: "@backstage/plugin-devtools@workspace:plugins/devtools" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-devtools-common": "workspace:^" + "@backstage/plugin-permission-react": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@backstage/types": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + msw: ^0.47.0 + react-json-view: ^1.21.3 + react-use: ^17.2.4 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + languageName: unknown + linkType: soft + "@backstage/plugin-dynatrace@workspace:^, @backstage/plugin-dynatrace@workspace:plugins/dynatrace": version: 0.0.0-use.local resolution: "@backstage/plugin-dynatrace@workspace:plugins/dynatrace" @@ -6292,8 +6337,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs" dependencies: - "@aws-sdk/client-sqs": ^3.208.0 - "@aws-sdk/types": ^3.208.0 + "@aws-sdk/client-sqs": ^3.310.0 + "@aws-sdk/types": ^3.310.0 "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" @@ -6991,39 +7036,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-home@npm:^0.5.1": - version: 0.5.1 - resolution: "@backstage/plugin-home@npm:0.5.1" - dependencies: - "@backstage/catalog-model": ^1.3.0 - "@backstage/config": ^1.0.7 - "@backstage/core-components": ^0.13.0 - "@backstage/core-plugin-api": ^1.5.1 - "@backstage/plugin-catalog-react": ^1.5.0 - "@backstage/theme": ^0.2.19 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core-v5": "npm:@rjsf/core@5.6.0" - "@rjsf/material-ui": 5.6.0 - "@rjsf/utils": 5.6.0 - "@rjsf/validator-ajv8": 5.6.0 - "@types/react": ^16.13.1 || ^17.0.0 - lodash: ^4.17.21 - object-hash: ^3.0.0 - react-grid-layout: ^1.3.4 - react-resizable: ^3.0.4 - react-use: ^17.2.4 - zod: ~3.21.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 0470e0d4848818c59fdf5c3765b769c22bf2b47e26b0ed0c80398baac6a8e1ac703e94152dc20498bfda790aec18a2af65605fcd8c6eb2e7ba7b85eb6ce80b69 - languageName: node - linkType: hard - -"@backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": +"@backstage/plugin-home@^0.5.1, @backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" dependencies: @@ -7054,7 +7067,6 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 msw: ^1.0.0 - object-hash: ^3.0.0 react-grid-layout: ^1.3.4 react-resizable: ^3.0.4 react-use: ^17.2.4 @@ -7124,6 +7136,7 @@ __metadata: express-promise-router: ^4.1.0 jenkins: ^1.0.0 msw: ^1.0.0 + node-fetch: ^2.6.7 supertest: ^6.1.6 winston: ^3.2.1 yn: ^4.0.0 @@ -7239,7 +7252,7 @@ __metadata: resolution: "@backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend" dependencies: "@aws-crypto/sha256-js": ^3.0.0 - "@aws-sdk/credential-providers": ^3.208.0 + "@aws-sdk/credential-providers": ^3.310.0 "@aws-sdk/signature-v4": ^3.310.0 "@azure/identity": ^2.0.4 "@backstage/backend-common": "workspace:^" @@ -7263,7 +7276,6 @@ __metadata: "@types/express": ^4.17.6 "@types/http-proxy-middleware": ^0.19.3 "@types/luxon": ^3.0.0 - aws4: ^1.11.0 compression: ^1.7.4 cors: ^2.8.5 express: ^4.17.1 @@ -7404,6 +7416,7 @@ __metadata: dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-tasks": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -7788,7 +7801,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.7.5, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -7826,7 +7839,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.12, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -8224,7 +8237,7 @@ __metadata: prom-client: ^14.0.1 supertest: ^6.1.3 uuid: ^8.2.0 - vm2: ^3.9.17 + vm2: ^3.9.18 wait-for-expect: ^3.0.2 winston: ^3.2.1 yaml: ^2.0.0 @@ -8365,7 +8378,7 @@ __metadata: "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 cross-fetch: ^3.1.5 - event-source-polyfill: 1.0.25 + event-source-polyfill: ^1.0.31 git-url-parse: ^13.0.0 humanize-duration: ^3.25.1 immer: ^9.0.1 @@ -8415,14 +8428,14 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" + "@backstage/integration-aws-node": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@elastic/elasticsearch": ^7.13.0 "@elastic/elasticsearch-mock": ^1.0.0 - "@opensearch-project/opensearch": ^2.0.0 + "@opensearch-project/opensearch": ^2.2.1 "@short.io/opensearch-mock": ^0.3.1 - aws-os-connection: ^0.2.0 - aws-sdk: ^2.948.0 + aws4: ^1.12.0 elastic-builder: ^2.16.0 lodash: ^4.17.21 uuid: ^8.3.2 @@ -9148,11 +9161,11 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-node@workspace:plugins/techdocs-node" dependencies: - "@aws-sdk/client-s3": ^3.208.0 - "@aws-sdk/credential-providers": ^3.208.0 - "@aws-sdk/lib-storage": ^3.208.0 - "@aws-sdk/node-http-handler": ^3.208.0 - "@aws-sdk/types": ^3.208.0 + "@aws-sdk/client-s3": ^3.310.0 + "@aws-sdk/credential-providers": ^3.310.0 + "@aws-sdk/lib-storage": ^3.310.0 + "@aws-sdk/node-http-handler": ^3.310.0 + "@aws-sdk/types": ^3.310.0 "@azure/identity": ^2.1.0 "@azure/storage-blob": ^12.5.0 "@backstage/backend-common": "workspace:^" @@ -9274,6 +9287,7 @@ __metadata: resolution: "@backstage/plugin-todo-backend@workspace:plugins/todo-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -9562,7 +9576,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.2.16, @backstage/theme@^0.2.18, @backstage/theme@^0.2.19, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@npm:^0.2.16, @backstage/theme@npm:^0.2.18, @backstage/theme@npm:^0.2.19": + version: 0.2.19 + resolution: "@backstage/theme@npm:0.2.19" + dependencies: + "@material-ui/core": ^4.12.2 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + react-dom: ^16.13.1 || ^17.0.0 + checksum: 93ca110a3f953d6d98b4a5f2163beaa1bd1f95adb66a593e85eb523a7012acf654b6148db54008a6434805a4bd9016d67e5c6a317bc56940ee6800aecbb97d6f + languageName: node + linkType: hard + +"@backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -9586,7 +9612,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@^1.0.4, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.3, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: @@ -10161,9 +10187,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/android-arm64@npm:0.17.18" +"@esbuild/android-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-arm64@npm:0.17.19" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -10182,9 +10208,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/android-arm@npm:0.17.18" +"@esbuild/android-arm@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-arm@npm:0.17.19" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -10196,9 +10222,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/android-x64@npm:0.17.18" +"@esbuild/android-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-x64@npm:0.17.19" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -10210,9 +10236,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/darwin-arm64@npm:0.17.18" +"@esbuild/darwin-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/darwin-arm64@npm:0.17.19" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10224,9 +10250,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/darwin-x64@npm:0.17.18" +"@esbuild/darwin-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/darwin-x64@npm:0.17.19" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -10238,9 +10264,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/freebsd-arm64@npm:0.17.18" +"@esbuild/freebsd-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/freebsd-arm64@npm:0.17.19" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -10252,9 +10278,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/freebsd-x64@npm:0.17.18" +"@esbuild/freebsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/freebsd-x64@npm:0.17.19" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -10266,9 +10292,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-arm64@npm:0.17.18" +"@esbuild/linux-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-arm64@npm:0.17.19" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -10280,9 +10306,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-arm@npm:0.17.18" +"@esbuild/linux-arm@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-arm@npm:0.17.19" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -10294,9 +10320,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-ia32@npm:0.17.18" +"@esbuild/linux-ia32@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-ia32@npm:0.17.19" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -10315,9 +10341,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-loong64@npm:0.17.18" +"@esbuild/linux-loong64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-loong64@npm:0.17.19" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -10329,9 +10355,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-mips64el@npm:0.17.18" +"@esbuild/linux-mips64el@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-mips64el@npm:0.17.19" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -10343,9 +10369,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-ppc64@npm:0.17.18" +"@esbuild/linux-ppc64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-ppc64@npm:0.17.19" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -10357,9 +10383,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-riscv64@npm:0.17.18" +"@esbuild/linux-riscv64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-riscv64@npm:0.17.19" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -10371,9 +10397,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-s390x@npm:0.17.18" +"@esbuild/linux-s390x@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-s390x@npm:0.17.19" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -10385,9 +10411,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/linux-x64@npm:0.17.18" +"@esbuild/linux-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-x64@npm:0.17.19" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -10399,9 +10425,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/netbsd-x64@npm:0.17.18" +"@esbuild/netbsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/netbsd-x64@npm:0.17.19" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -10413,9 +10439,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/openbsd-x64@npm:0.17.18" +"@esbuild/openbsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/openbsd-x64@npm:0.17.19" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -10427,9 +10453,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/sunos-x64@npm:0.17.18" +"@esbuild/sunos-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/sunos-x64@npm:0.17.19" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -10441,9 +10467,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/win32-arm64@npm:0.17.18" +"@esbuild/win32-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-arm64@npm:0.17.19" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -10455,9 +10481,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/win32-ia32@npm:0.17.18" +"@esbuild/win32-ia32@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-ia32@npm:0.17.19" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -10469,9 +10495,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.17.18": - version: 0.17.18 - resolution: "@esbuild/win32-x64@npm:0.17.18" +"@esbuild/win32-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-x64@npm:0.17.19" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -13327,8 +13353,8 @@ __metadata: linkType: hard "@octokit/request@npm:^6.0.0": - version: 6.2.3 - resolution: "@octokit/request@npm:6.2.3" + version: 6.2.5 + resolution: "@octokit/request@npm:6.2.5" dependencies: "@octokit/endpoint": ^7.0.0 "@octokit/request-error": ^3.0.0 @@ -13336,7 +13362,7 @@ __metadata: is-plain-object: ^5.0.0 node-fetch: ^2.6.7 universal-user-agent: ^6.0.0 - checksum: fef4097be8375d20bb0b3276d8a3adf866ec628f2b0664d334f3c29b92157da847899497abdc7a5be540053819b55564990543175ad48f04e9e6f25f0395d4d3 + checksum: 856451ea8cc6b1dd0f6e350a141e65c318b5e3a25b8dea373d3afd115f9a3077535a0330f5d90e9db81dc3234dba1dd64edd31e68f639553baa10b4d02b99498 languageName: node linkType: hard @@ -13457,7 +13483,7 @@ __metadata: languageName: node linkType: hard -"@opensearch-project/opensearch@npm:^2.0.0": +"@opensearch-project/opensearch@npm:^2.2.1": version: 2.2.1 resolution: "@opensearch-project/opensearch@npm:2.2.1" dependencies: @@ -15666,14 +15692,14 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.30, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.17.34 - resolution: "@types/express-serve-static-core@npm:4.17.34" + version: 4.17.35 + resolution: "@types/express-serve-static-core@npm:4.17.35" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 3b5242e7d6cfecca5300635fd2af0f63aca3a92754da79a4a355c4d85b57099aa2cabb1c8557fc38a8a9e6f0be996339140ad017e5be405ea1b877a8294a136d + checksum: cc8995d10c6feda475ec1b3a0e69eb0f35f21ab6b49129ad5c6f279e0bc5de8175bc04ec51304cb79a43eec3ed2f5a1e01472eb6d5f827b8c35c6ca8ad24eb6e languageName: node linkType: hard @@ -16223,9 +16249,9 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0": - version: 20.1.0 - resolution: "@types/node@npm:20.1.0" - checksum: c6d9afa9aa78b4b4348c69ece94975be70346b144c278f1395694a10ef919d7db300018101b6f9245e6bdd76674a5327d2d14829092f3d5295e858cff5f22a66 + version: 20.1.4 + resolution: "@types/node@npm:20.1.4" + checksum: bffa6a6e92831cc805b13658c55be8e04abe3202d5e57ddd7fee4cfbe269656a1f475909a9f9514e1aff50310d0d90c516ac2c649cb6f1c77d4b1079c2fd1e88 languageName: node linkType: hard @@ -16244,9 +16270,9 @@ __metadata: linkType: hard "@types/node@npm:^14.14.31": - version: 14.18.45 - resolution: "@types/node@npm:14.18.45" - checksum: 2857cd1912d70f6a97b9d8085088b12ab80bcaa06e4ea20535020167bfcbc6bea9469fafc437acddd34b07e3d94b1d35bcbd51d960c8841ab1a675166e97d8b9 + version: 14.18.47 + resolution: "@types/node@npm:14.18.47" + checksum: 249467fa37e60bb7ce631616a5fea53f3b957a6792c6a09f7db7cdff85a7410c9e657dd9fa54bcc9d878e58f35407ce35169b84556f46b2154f90bc71063e1d0 languageName: node linkType: hard @@ -16258,16 +16284,16 @@ __metadata: linkType: hard "@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.9.2": - version: 16.18.26 - resolution: "@types/node@npm:16.18.26" - checksum: 2a746b3f9e97e00aa5d1d8cce36c5b75d5504df15e82647ad1fadbc3435ea4491203d044bbaa595edc2ab25a9ab820793f9d38dba753ad150929335fa21e24d4 + version: 16.18.30 + resolution: "@types/node@npm:16.18.30" + checksum: 2975519e337a3f29c495b97aa7510ef3f4ac5d3c9356f7886698a4abf8b12641c1f1247512b525599cba6aefe774735ef25fc83555e989033bdbcc4a2b1c7401 languageName: node linkType: hard "@types/node@npm:^18.11.17": - version: 18.16.5 - resolution: "@types/node@npm:18.16.5" - checksum: b6df96a76a7655cd944794197cf63f5269e5034041bc355f4f243cb3f185ad3e1948011b6f0ac66c22434e50bc53a20ec3a9d95ad284f0e3819813d309d1650b + version: 18.16.9 + resolution: "@types/node@npm:18.16.9" + checksum: 7fe0ef372ba8b157bd646efe29b0ece92ccb9f455171a7ceb4c92d6b490789ff0f14411b1dc6ad203351a0efa2b435072dfab5566fb6eaaaa5cd549e1fb22afa languageName: node linkType: hard @@ -16400,6 +16426,13 @@ __metadata: languageName: node linkType: hard +"@types/ping@npm:^0.4.1": + version: 0.4.1 + resolution: "@types/ping@npm:0.4.1" + checksum: 9b94837fe66df70558c5a42b0e0c8371b4950ab56b96c42c8df809ff2cf52477dd0a7e01d2e6b38af8bb6683b3dcb54587960b96b4b1f3d40fdb529aea348ad0 + languageName: node + linkType: hard + "@types/pluralize@npm:^0.0.29": version: 0.0.29 resolution: "@types/pluralize@npm:0.0.29" @@ -16865,12 +16898,12 @@ __metadata: linkType: hard "@types/tar@npm:^6.1.1": - version: 6.1.4 - resolution: "@types/tar@npm:6.1.4" + version: 6.1.5 + resolution: "@types/tar@npm:6.1.5" dependencies: "@types/node": "*" minipass: ^4.0.0 - checksum: 48a1f6b8665ed03f37f74966cfe991a33d6e85cee28aaa6ef42c7ca8448cdbc1e2ca96b473b6b53f1d7bd91423ae0dcfe54a295607d7ac4b4cbb9dbf167df7fa + checksum: 1efa71c8d72f2b02d16ffecb65c4a96be9dacce000c4207532a686477386524dd99b6e26904319354be3ac9ac4d41296a0cb9cf87d05f8f21ae31c68fe446348 languageName: node linkType: hard @@ -18394,18 +18427,6 @@ __metadata: languageName: node linkType: hard -"aws-os-connection@npm:^0.2.0": - version: 0.2.0 - resolution: "aws-os-connection@npm:0.2.0" - dependencies: - aws4: ^1.11.0 - peerDependencies: - "@opensearch-project/opensearch": 2 - aws-sdk: ">=2" - checksum: 1708ffd9bdc5f7bd6b8447f97859936a8657f4df567f61f12dacd040e6f1a25020bbea8027bb28f19fe27d171a0d3a5090c2d84d6f752bb04e387640413fec7c - languageName: node - linkType: hard - "aws-sdk-client-mock-jest@npm:^2.0.0": version: 2.1.1 resolution: "aws-sdk-client-mock-jest@npm:2.1.1" @@ -18440,7 +18461,7 @@ __metadata: languageName: node linkType: hard -"aws-sdk@npm:^2.1231.0, aws-sdk@npm:^2.840.0, aws-sdk@npm:^2.948.0": +"aws-sdk@npm:^2.1231.0": version: 2.1279.0 resolution: "aws-sdk@npm:2.1279.0" dependencies: @@ -18465,7 +18486,7 @@ __metadata: languageName: node linkType: hard -"aws4@npm:^1.11.0, aws4@npm:^1.8.0": +"aws4@npm:^1.11.0, aws4@npm:^1.12.0, aws4@npm:^1.8.0": version: 1.12.0 resolution: "aws4@npm:1.12.0" checksum: 68f79708ac7c335992730bf638286a3ee0a645cf12575d557860100767c500c08b30e24726b9f03265d74116417f628af78509e1333575e9f8d52a80edfe8cbc @@ -18801,6 +18822,13 @@ __metadata: languageName: node linkType: hard +"base16@npm:^1.0.0": + version: 1.0.0 + resolution: "base16@npm:1.0.0" + checksum: 0cd449a2db0f0f957e4b6b57e33bc43c9e20d4f1dd744065db94b5da35e8e71fa4dc4bc7a901e59a84d5f8b6936e3c520e2471787f667fc155fb0f50d8540f5d + languageName: node + linkType: hard + "base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -20552,6 +20580,16 @@ __metadata: languageName: node linkType: hard +"connect-session-knex@npm:^3.0.1": + version: 3.0.1 + resolution: "connect-session-knex@npm:3.0.1" + dependencies: + bluebird: ^3.7.2 + knex: ^2.3.0 + checksum: f5a80c3c34d30e7cd4e79a6aae09d112825986d51ddc3a4563ef95ade425178239d4e3e05420fb3b6204b2353b0dfd754d318b288989b539583f6c0e52758b7a + languageName: node + linkType: hard + "consola@npm:^2.15.0": version: 2.15.3 resolution: "consola@npm:2.15.3" @@ -20899,7 +20937,7 @@ __metadata: languageName: node linkType: hard -"cross-fetch@npm:3.1.5, cross-fetch@npm:^3.0.4, cross-fetch@npm:^3.1.3, cross-fetch@npm:^3.1.5": +"cross-fetch@npm:3.1.5": version: 3.1.5 resolution: "cross-fetch@npm:3.1.5" dependencies: @@ -20908,6 +20946,15 @@ __metadata: languageName: node linkType: hard +"cross-fetch@npm:^3.1.3, cross-fetch@npm:^3.1.5": + version: 3.1.6 + resolution: "cross-fetch@npm:3.1.6" + dependencies: + node-fetch: ^2.6.11 + checksum: 704b3519ab7de488328cc49a52cf1aa14132ec748382be5b9557b22398c33ffa7f8c2530e8a97ed8cb55da52b0a9740a9791d361271c4591910501682d981d9c + languageName: node + linkType: hard + "cross-spawn@npm:^5.1.0": version: 5.1.0 resolution: "cross-spawn@npm:5.1.0" @@ -22884,31 +22931,31 @@ __metadata: linkType: hard "esbuild@npm:^0.17.0": - version: 0.17.18 - resolution: "esbuild@npm:0.17.18" + version: 0.17.19 + resolution: "esbuild@npm:0.17.19" dependencies: - "@esbuild/android-arm": 0.17.18 - "@esbuild/android-arm64": 0.17.18 - "@esbuild/android-x64": 0.17.18 - "@esbuild/darwin-arm64": 0.17.18 - "@esbuild/darwin-x64": 0.17.18 - "@esbuild/freebsd-arm64": 0.17.18 - "@esbuild/freebsd-x64": 0.17.18 - "@esbuild/linux-arm": 0.17.18 - "@esbuild/linux-arm64": 0.17.18 - "@esbuild/linux-ia32": 0.17.18 - "@esbuild/linux-loong64": 0.17.18 - "@esbuild/linux-mips64el": 0.17.18 - "@esbuild/linux-ppc64": 0.17.18 - "@esbuild/linux-riscv64": 0.17.18 - "@esbuild/linux-s390x": 0.17.18 - "@esbuild/linux-x64": 0.17.18 - "@esbuild/netbsd-x64": 0.17.18 - "@esbuild/openbsd-x64": 0.17.18 - "@esbuild/sunos-x64": 0.17.18 - "@esbuild/win32-arm64": 0.17.18 - "@esbuild/win32-ia32": 0.17.18 - "@esbuild/win32-x64": 0.17.18 + "@esbuild/android-arm": 0.17.19 + "@esbuild/android-arm64": 0.17.19 + "@esbuild/android-x64": 0.17.19 + "@esbuild/darwin-arm64": 0.17.19 + "@esbuild/darwin-x64": 0.17.19 + "@esbuild/freebsd-arm64": 0.17.19 + "@esbuild/freebsd-x64": 0.17.19 + "@esbuild/linux-arm": 0.17.19 + "@esbuild/linux-arm64": 0.17.19 + "@esbuild/linux-ia32": 0.17.19 + "@esbuild/linux-loong64": 0.17.19 + "@esbuild/linux-mips64el": 0.17.19 + "@esbuild/linux-ppc64": 0.17.19 + "@esbuild/linux-riscv64": 0.17.19 + "@esbuild/linux-s390x": 0.17.19 + "@esbuild/linux-x64": 0.17.19 + "@esbuild/netbsd-x64": 0.17.19 + "@esbuild/openbsd-x64": 0.17.19 + "@esbuild/sunos-x64": 0.17.19 + "@esbuild/win32-arm64": 0.17.19 + "@esbuild/win32-ia32": 0.17.19 + "@esbuild/win32-x64": 0.17.19 dependenciesMeta: "@esbuild/android-arm": optional: true @@ -22956,7 +23003,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 900b333f649fd89804216fb61fb5a0ffadc6dc37a2ec3b5981b588f72821676ea649a7c0ec785f0dbe6e774080b084c8af5f6ee7adbc1b138faf2a8c35e2c69c + checksum: ac11b1a5a6008e4e37ccffbd6c2c054746fc58d0ed4a2f9ee643bd030cfcea9a33a235087bc777def8420f2eaafb3486e76adb7bdb7241a9143b43a69a10afd8 languageName: node linkType: hard @@ -23528,6 +23575,13 @@ __metadata: languageName: node linkType: hard +"event-source-polyfill@npm:^1.0.31": + version: 1.0.31 + resolution: "event-source-polyfill@npm:1.0.31" + checksum: 973f226404e2a1b14ed7ef15c718b89e213b41d7cfeeb1c10937fd09229f13904f3d7c3075ab28ccf858c213007559908eecdd577577330352f53a351383dd75 + languageName: node + linkType: hard + "event-stream@npm:=3.3.4": version: 3.3.4 resolution: "event-stream@npm:3.3.4" @@ -23635,6 +23689,7 @@ __metadata: "@backstage/plugin-cloudbuild": "workspace:^" "@backstage/plugin-code-coverage": "workspace:^" "@backstage/plugin-cost-insights": "workspace:^" + "@backstage/plugin-devtools": "workspace:^" "@backstage/plugin-dynatrace": "workspace:^" "@backstage/plugin-entity-feedback": "workspace:^" "@backstage/plugin-explore": "workspace:^" @@ -23758,6 +23813,7 @@ __metadata: "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-code-coverage-backend": "workspace:^" + "@backstage/plugin-devtools-backend": "workspace:^" "@backstage/plugin-entity-feedback-backend": "workspace:^" "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" @@ -24239,6 +24295,15 @@ __metadata: languageName: node linkType: hard +"fbemitter@npm:^3.0.0": + version: 3.0.0 + resolution: "fbemitter@npm:3.0.0" + dependencies: + fbjs: ^3.0.0 + checksum: 069690b8cdff3521ade3c9beb92ba0a38d818a86ef36dff8690e66749aef58809db4ac0d6938eb1cacea2dbef5f2a508952d455669590264cdc146bbe839f605 + languageName: node + linkType: hard + "fbjs-css-vars@npm:^1.0.0": version: 1.0.2 resolution: "fbjs-css-vars@npm:1.0.2" @@ -24261,18 +24326,18 @@ __metadata: languageName: node linkType: hard -"fbjs@npm:^3.0.0": - version: 3.0.0 - resolution: "fbjs@npm:3.0.0" +"fbjs@npm:^3.0.0, fbjs@npm:^3.0.1": + version: 3.0.4 + resolution: "fbjs@npm:3.0.4" dependencies: - cross-fetch: ^3.0.4 + cross-fetch: ^3.1.5 fbjs-css-vars: ^1.0.0 loose-envify: ^1.0.0 object-assign: ^4.1.0 promise: ^7.1.1 setimmediate: ^1.0.5 - ua-parser-js: ^0.7.18 - checksum: 85ec57d8dbeddd7c82bf8f111a3c7de1abc1f4d7c603d6ccbcc1ec8dce35ff5b7a113dd34acbf7930093e5533c37a2298a92d342077f967bef34dc7cf2f3f07e + ua-parser-js: ^0.7.30 + checksum: 8b23a3550fcda8a9109fca9475a3416590c18bb6825ea884192864ed686f67fcd618e308a140c9e5444fbd0168732e1ff3c092ba3d0c0ae1768969f32ba280c7 languageName: node linkType: hard @@ -24516,6 +24581,18 @@ __metadata: languageName: node linkType: hard +"flux@npm:^4.0.1": + version: 4.0.4 + resolution: "flux@npm:4.0.4" + dependencies: + fbemitter: ^3.0.0 + fbjs: ^3.0.1 + peerDependencies: + react: ^15.0.2 || ^16.0.0 || ^17.0.0 + checksum: 8fa5c2f9322258de3e331f67c6f1078a7f91c4dec9dbe8a54c4b8a80eed19a4f91889028b768668af4a796e8f2ee75e461e1571b8615432a3920ae95cc4ff794 + languageName: node + linkType: hard + "fn.name@npm:1.x.x": version: 1.1.0 resolution: "fn.name@npm:1.1.0" @@ -28990,7 +29067,7 @@ __metadata: languageName: node linkType: hard -"knex@npm:^2.0.0, knex@npm:^2.4.2": +"knex@npm:^2.0.0, knex@npm:^2.3.0, knex@npm:^2.4.2": version: 2.4.2 resolution: "knex@npm:2.4.2" dependencies: @@ -29456,6 +29533,13 @@ __metadata: languageName: node linkType: hard +"lodash.curry@npm:^4.0.1": + version: 4.1.1 + resolution: "lodash.curry@npm:4.1.1" + checksum: 9192b70fe7df4d1ff780c0260bee271afa9168c93fe4fa24bc861900240531b59781b5fdaadf4644fea8f4fbcd96f0700539ab294b579ffc1022c6c15dcc462a + languageName: node + linkType: hard + "lodash.debounce@npm:^4, lodash.debounce@npm:^4.0.8": version: 4.0.8 resolution: "lodash.debounce@npm:4.0.8" @@ -29491,6 +29575,13 @@ __metadata: languageName: node linkType: hard +"lodash.flow@npm:^3.3.0": + version: 3.5.0 + resolution: "lodash.flow@npm:3.5.0" + checksum: a9a62ad344e3c5a1f42bc121da20f64dd855aaafecee24b1db640f29b88bd165d81c37ff7e380a7191de6f70b26f5918abcebbee8396624f78f3618a0b18634c + languageName: node + linkType: hard + "lodash.get@npm:^4.4.2": version: 4.4.2 resolution: "lodash.get@npm:4.4.2" @@ -31107,6 +31198,41 @@ __metadata: languageName: node linkType: hard +"msw@npm:^0.47.0": + version: 0.47.4 + resolution: "msw@npm:0.47.4" + dependencies: + "@mswjs/cookies": ^0.2.2 + "@mswjs/interceptors": ^0.17.5 + "@open-draft/until": ^1.0.3 + "@types/cookie": ^0.4.1 + "@types/js-levenshtein": ^1.1.1 + chalk: 4.1.1 + chokidar: ^3.4.2 + cookie: ^0.4.2 + graphql: ^15.0.0 || ^16.0.0 + headers-polyfill: ^3.1.0 + inquirer: ^8.2.0 + is-node-process: ^1.0.1 + js-levenshtein: ^1.1.6 + node-fetch: ^2.6.7 + outvariant: ^1.3.0 + path-to-regexp: ^6.2.0 + statuses: ^2.0.0 + strict-event-emitter: ^0.2.6 + type-fest: ^2.19.0 + yargs: ^17.3.1 + peerDependencies: + typescript: ">= 4.2.x <= 4.8.x" + peerDependenciesMeta: + typescript: + optional: true + bin: + msw: cli/index.js + checksum: 10ff632641d40384d6622abf4df6399e4ae649db0f676b5d1ee2d0a515ec96f33abe9d4fecba08cdba4b2e43255af419da9eefc020d40a7e10669d0906457197 + languageName: node + linkType: hard + "msw@npm:^0.49.0": version: 0.49.3 resolution: "msw@npm:0.49.3" @@ -31459,9 +31585,9 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.5, node-fetch@npm:^2.6.7": - version: 2.6.9 - resolution: "node-fetch@npm:2.6.9" +"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.11, node-fetch@npm:^2.6.5, node-fetch@npm:^2.6.7": + version: 2.6.11 + resolution: "node-fetch@npm:2.6.11" dependencies: whatwg-url: ^5.0.0 peerDependencies: @@ -31469,7 +31595,7 @@ __metadata: peerDependenciesMeta: encoding: optional: true - checksum: acb04f9ce7224965b2b59e71b33c639794d8991efd73855b0b250921382b38331ffc9d61bce502571f6cc6e11a8905ca9b1b6d4aeb586ab093e2756a1fd190d0 + checksum: 249d0666a9497553384d46b5ab296ba223521ac88fed4d8a17d6ee6c2efb0fc890f3e8091cafe7f9fba8151a5b8d925db2671543b3409a56c3cd522b468b47b3 languageName: node linkType: hard @@ -33178,6 +33304,13 @@ __metadata: languageName: node linkType: hard +"ping@npm:^0.4.1": + version: 0.4.4 + resolution: "ping@npm:0.4.4" + checksum: cab10af309312e3a6822eccb7f323f0c9a1e17ef5895954114e31b6a1cced5e2ced3563990b79c66d074372e75aa4c846d9001120ee296b365de6a2adef5b8f9 + languageName: node + linkType: hard + "pinkie-promise@npm:^2.0.0": version: 2.0.1 resolution: "pinkie-promise@npm:2.0.1" @@ -34266,6 +34399,13 @@ __metadata: languageName: node linkType: hard +"pure-color@npm:^1.2.0": + version: 1.3.0 + resolution: "pure-color@npm:1.3.0" + checksum: 646d8bed6e6eab89affdd5e2c11f607a85b631a7fb03c061dfa658eb4dc4806881a15feed2ac5fd8c0bad8c00c632c640d5b1cb8b9a972e6e947393a1329371b + languageName: node + linkType: hard + "pvtsutils@npm:^1.3.2": version: 1.3.2 resolution: "pvtsutils@npm:1.3.2" @@ -34282,7 +34422,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0, qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.9.1, qs@npm:^6.9.4, qs@npm:^6.9.6": +"qs@npm:6.11.0": version: 6.11.0 resolution: "qs@npm:6.11.0" dependencies: @@ -34291,6 +34431,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.9.1, qs@npm:^6.9.4, qs@npm:^6.9.6": + version: 6.11.2 + resolution: "qs@npm:6.11.2" + dependencies: + side-channel: ^1.0.4 + checksum: e812f3c590b2262548647d62f1637b6989cc56656dc960b893fe2098d96e1bd633f36576f4cd7564dfbff9db42e17775884db96d846bebe4f37420d073ecdc0b + languageName: node + linkType: hard + "qs@npm:~6.5.2": version: 6.5.3 resolution: "qs@npm:6.5.3" @@ -34498,6 +34647,18 @@ __metadata: languageName: node linkType: hard +"react-base16-styling@npm:^0.6.0": + version: 0.6.0 + resolution: "react-base16-styling@npm:0.6.0" + dependencies: + base16: ^1.0.0 + lodash.curry: ^4.0.1 + lodash.flow: ^3.3.0 + pure-color: ^1.2.0 + checksum: 00a12dddafc8a9025cca933b0dcb65fca41c81fa176d1fc3a6a9d0242127042e2c0a604f4c724a3254dd2c6aeb5ef55095522ff22f5462e419641c1341a658e4 + languageName: node + linkType: hard + "react-beautiful-dnd@npm:^13.0.0": version: 13.0.0 resolution: "react-beautiful-dnd@npm:13.0.0" @@ -34767,6 +34928,21 @@ __metadata: languageName: node linkType: hard +"react-json-view@npm:^1.21.3": + version: 1.21.3 + resolution: "react-json-view@npm:1.21.3" + dependencies: + flux: ^4.0.1 + react-base16-styling: ^0.6.0 + react-lifecycles-compat: ^3.0.4 + react-textarea-autosize: ^8.3.2 + peerDependencies: + react: ^17.0.0 || ^16.3.0 || ^15.5.4 + react-dom: ^17.0.0 || ^16.3.0 || ^15.5.4 + checksum: 5718bcd9210ad5b06eb9469cf8b9b44be9498845a7702e621343618e8251f26357e6e1c865532cf170db6165df1cb30202787e057309d8848c220bc600ec0d1a + languageName: node + linkType: hard + "react-lifecycles-compat@npm:^3.0.2, react-lifecycles-compat@npm:^3.0.4": version: 3.0.4 resolution: "react-lifecycles-compat@npm:3.0.4" @@ -35034,6 +35210,19 @@ __metadata: languageName: node linkType: hard +"react-textarea-autosize@npm:^8.3.2": + version: 8.4.1 + resolution: "react-textarea-autosize@npm:8.4.1" + dependencies: + "@babel/runtime": ^7.20.13 + use-composed-ref: ^1.3.0 + use-latest: ^1.2.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: b200437cd68938c23b13944fe6fdfeb32a6d949ac88588307f14d6fcdaba3044b8c7d8e239851b081f2101d433b93d4cf5aa027543b170b84f2a0cbe6fc9093f + languageName: node + linkType: hard + "react-transition-group@npm:2.9.0, react-transition-group@npm:^2.2.1": version: 2.9.0 resolution: "react-transition-group@npm:2.9.0" @@ -35100,12 +35289,12 @@ __metadata: linkType: hard "react-virtualized-auto-sizer@npm:^1.0.11, react-virtualized-auto-sizer@npm:^1.0.6": - version: 1.0.15 - resolution: "react-virtualized-auto-sizer@npm:1.0.15" + version: 1.0.16 + resolution: "react-virtualized-auto-sizer@npm:1.0.16" peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc - checksum: db6716fff307dcd2b2492ee0539d5fe2922ea067f91a69969aed6ac03f46db105e993e0a9f946e74b1fb3b9caf88ce5629bf1132e3a995457f42b559979d6708 + checksum: 68319e26b162dd3f5186ed88f3977658a9da5963a250567d7fe0cd44671a87b765652248d3c39e1f02aa46c22df51a34748e11f436a70296b37ee509be89dab6 languageName: node linkType: hard @@ -37398,7 +37587,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:2.0.1": +"statuses@npm:2.0.1, statuses@npm:^2.0.0": version: 2.0.1 resolution: "statuses@npm:2.0.1" checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb @@ -37500,12 +37689,12 @@ __metadata: languageName: node linkType: hard -"strict-event-emitter@npm:^0.2.4": - version: 0.2.7 - resolution: "strict-event-emitter@npm:0.2.7" +"strict-event-emitter@npm:^0.2.4, strict-event-emitter@npm:^0.2.6": + version: 0.2.8 + resolution: "strict-event-emitter@npm:0.2.8" dependencies: events: ^3.3.0 - checksum: 111691e7d3fce0810586ccd8e8234af883ad3b121ef69091c7e260c32299d1ba085a95238ad09b43478bc5e9e80370f2fcb8114716e343be6f44bfc08fab4142 + checksum: 6ac06fe72a6ee6ae64d20f1dd42838ea67342f1b5f32b03b3050d73ee6ecee44b4d5c4ed2965a7154b47991e215f373d4e789e2b2be2769cd80e356126c2ca53 languageName: node linkType: hard @@ -39069,7 +39258,7 @@ __metadata: languageName: node linkType: hard -"ua-parser-js@npm:^0.7.18, ua-parser-js@npm:^0.7.30": +"ua-parser-js@npm:^0.7.30": version: 0.7.33 resolution: "ua-parser-js@npm:0.7.33" checksum: 1510e9ec26fcaf0d8c6ae8f1078a8230e8816f083e1b5f453ea19d06b8ef2b8a596601c92148fd41899e8b3e5f83fa69c42332bd5729b931a721040339831696 @@ -39469,6 +39658,15 @@ __metadata: languageName: node linkType: hard +"use-composed-ref@npm:^1.3.0": + version: 1.3.0 + resolution: "use-composed-ref@npm:1.3.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: f771cbadfdc91e03b7ab9eb32d0fc0cc647755711801bf507e891ad38c4bbc5f02b2509acadf9c965ec9c5f2f642fd33bdfdfb17b0873c4ad0a9b1f5e5e724bf + languageName: node + linkType: hard + "use-deep-compare-effect@npm:^1.8.1": version: 1.8.1 resolution: "use-deep-compare-effect@npm:1.8.1" @@ -39491,6 +39689,32 @@ __metadata: languageName: node linkType: hard +"use-isomorphic-layout-effect@npm:^1.1.1": + version: 1.1.2 + resolution: "use-isomorphic-layout-effect@npm:1.1.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: a6532f7fc9ae222c3725ff0308aaf1f1ddbd3c00d685ef9eee6714fd0684de5cb9741b432fbf51e61a784e2955424864f7ea9f99734a02f237b17ad3e18ea5cb + languageName: node + linkType: hard + +"use-latest@npm:^1.2.1": + version: 1.2.1 + resolution: "use-latest@npm:1.2.1" + dependencies: + use-isomorphic-layout-effect: ^1.1.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: ed3f2ddddf6f21825e2ede4c2e0f0db8dcce5129802b69d1f0575fc1b42380436e8c76a6cd885d4e9aa8e292e60fb8b959c955f33c6a9123b83814a1a1875367 + languageName: node + linkType: hard + "use-memo-one@npm:^1.1.1": version: 1.1.1 resolution: "use-memo-one@npm:1.1.1" @@ -39840,15 +40064,15 @@ __metadata: languageName: node linkType: hard -"vm2@npm:^3.9.17": - version: 3.9.17 - resolution: "vm2@npm:3.9.17" +"vm2@npm:^3.9.18": + version: 3.9.19 + resolution: "vm2@npm:3.9.19" dependencies: acorn: ^8.7.0 acorn-walk: ^8.2.0 bin: vm2: bin/vm2 - checksum: 9a03740a40ab2be5e3348a95fb31512da1a3c85318febb07e5299fa103ff05bcd7b6f458211fa38a1281dc27beccd04ff90355fc1d34fe2ee6ca10d0bb8c6f35 + checksum: fc6cf553134145cd7bb5246985bf242b056e3fb5ea71e2eef6710b2a5d6c6119cc6bc960435ff62480ee82efb43369be8f4db07b6690916ae7d3b2e714f395d8 languageName: node linkType: hard